Application Android et IOS pour l'amicale des élèves https://play.google.com/store/apps/details?id=fr.amicaleinsat.application
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ConnectionManager.js 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. // @flow
  2. import * as SecureStore from 'expo-secure-store';
  3. export const ERROR_TYPE = {
  4. BAD_CREDENTIALS: 0,
  5. CONNECTION_ERROR: 1,
  6. SAVE_TOKEN: 2,
  7. NO_TOKEN: 3,
  8. NO_CONSENT: 4,
  9. };
  10. const AUTH_URL = "https://www.amicale-insat.fr/api/password";
  11. export default class ConnectionManager {
  12. static instance: ConnectionManager | null = null;
  13. #email: string;
  14. #token: string | null;
  15. listeners: Array<Function>;
  16. constructor() {
  17. this.#token = null;
  18. this.listeners = [];
  19. }
  20. /**
  21. * Get this class instance or create one if none is found
  22. * @returns {ConnectionManager}
  23. */
  24. static getInstance(): ConnectionManager {
  25. return ConnectionManager.instance === null ?
  26. ConnectionManager.instance = new ConnectionManager() :
  27. ConnectionManager.instance;
  28. }
  29. getToken() {
  30. return this.#token;
  31. }
  32. onLoginStateChange(newState: boolean) {
  33. for (let i = 0; i < this.listeners.length; i++) {
  34. if (this.listeners[i] !== undefined)
  35. this.listeners[i](newState);
  36. }
  37. }
  38. addLoginStateListener(listener: Function) {
  39. this.listeners.push(listener);
  40. }
  41. async recoverLogin() {
  42. return new Promise((resolve, reject) => {
  43. if (this.getToken() !== null)
  44. resolve(this.getToken());
  45. else {
  46. SecureStore.getItemAsync('token')
  47. .then((token) => {
  48. this.#token = token;
  49. if (token !== null) {
  50. this.onLoginStateChange(true);
  51. resolve(token);
  52. } else
  53. reject(false);
  54. })
  55. .catch(error => {
  56. reject(false);
  57. });
  58. }
  59. });
  60. }
  61. isLoggedIn() {
  62. return this.getToken() !== null;
  63. }
  64. async saveLogin(email: string, token: string) {
  65. return new Promise((resolve, reject) => {
  66. SecureStore.setItemAsync('token', token)
  67. .then(() => {
  68. this.#token = token;
  69. this.#email = email;
  70. this.onLoginStateChange(true);
  71. resolve(true);
  72. })
  73. .catch(error => {
  74. reject(false);
  75. });
  76. });
  77. }
  78. async disconnect() {
  79. return new Promise((resolve, reject) => {
  80. SecureStore.deleteItemAsync('token')
  81. .then(() => {
  82. this.#token = null;
  83. this.onLoginStateChange(false);
  84. resolve(true);
  85. })
  86. .catch((error) => {
  87. reject(false);
  88. });
  89. });
  90. }
  91. async connect(email: string, password: string) {
  92. let data = {
  93. email: email,
  94. password: password,
  95. };
  96. return new Promise((resolve, reject) => {
  97. fetch(AUTH_URL, {
  98. method: 'POST',
  99. headers: new Headers({
  100. 'Accept': 'application/json',
  101. 'Content-Type': 'application/json',
  102. }),
  103. body: JSON.stringify(data)
  104. }).then(async (response) => response.json())
  105. .then((data) => {
  106. if (this.isConnectionResponseValid(data)) {
  107. if (data.state) {
  108. this.saveLogin(email, data.token)
  109. .then(() => {
  110. resolve(true);
  111. })
  112. .catch(() => {
  113. reject(ERROR_TYPE.SAVE_TOKEN);
  114. });
  115. } else if (data.data !== undefined
  116. && data.data.consent !== undefined
  117. && !data.data.consent)
  118. reject(ERROR_TYPE.NO_CONSENT);
  119. else
  120. reject(ERROR_TYPE.BAD_CREDENTIALS);
  121. } else
  122. reject(ERROR_TYPE.CONNECTION_ERROR);
  123. })
  124. .catch((error) => {
  125. reject(ERROR_TYPE.CONNECTION_ERROR);
  126. });
  127. });
  128. }
  129. isRequestResponseValid(response: Object) {
  130. let valid = response !== undefined
  131. && response.state !== undefined
  132. && typeof response.state === "boolean";
  133. if (valid && response.state)
  134. valid = valid
  135. && response.data !== undefined
  136. && typeof response.data === "object";
  137. return valid;
  138. }
  139. isConnectionResponseValid(response: Object) {
  140. let valid = response !== undefined
  141. && response.state !== undefined
  142. && typeof response.state === "boolean";
  143. if (valid && response.state)
  144. valid = valid
  145. && response.token !== undefined
  146. && response.token !== ''
  147. && typeof response.token === "string";
  148. return valid;
  149. }
  150. async authenticatedRequest(url: string) {
  151. return new Promise((resolve, reject) => {
  152. if (this.getToken() !== null) {
  153. fetch(url, {
  154. method: 'POST',
  155. headers: new Headers({
  156. 'Accept': 'application/json',
  157. 'Content-Type': 'application/json',
  158. }),
  159. body: JSON.stringify({token: this.getToken()})
  160. }).then(async (response) => response.json())
  161. .then((data) => {
  162. if (this.isRequestResponseValid(data)) {
  163. if (data.state)
  164. resolve(data.data);
  165. else
  166. reject(ERROR_TYPE.BAD_CREDENTIALS);
  167. } else
  168. reject(ERROR_TYPE.CONNECTION_ERROR);
  169. })
  170. .catch(() => {
  171. reject(ERROR_TYPE.CONNECTION_ERROR);
  172. });
  173. } else
  174. reject(ERROR_TYPE.NO_TOKEN);
  175. });
  176. }
  177. }