/ src / api / refresh.ts
refresh.ts
 1  import type { ClientUserStatus } from "~/definitions/client-user-status";
 2  import type { Error as ServerError } from "~/definitions/error";
 3  import type { Tokens } from "~/definitions/tokens";
 4  import { defaultFetcher, type Fetcher, type Request } from "@literate.ink/utilities";
 5  import { CLIENT_TYPE, createRouteREST, SERVICE_VERSION } from "~/core/constants";
 6  
 7  import { type Identification, NotRefreshableError, ReauthenticateError } from "~/models";
 8  import { otp } from "./private/otp";
 9  export type { ClientUserStatus, Tokens };
10  
11  export const refresh = async (identification: Identification, secret: string, fetcher: Fetcher = defaultFetcher): Promise<void> => {
12    const passOTP = secret + otp(identification);
13  
14    const request: Request = {
15      headers: {
16        "Authorization": `Bearer ${identification.accessToken}`,
17        "channel": "AIZ",
18        "clientVersion": SERVICE_VERSION,
19        "Content-Type": "application/x-www-form-urlencoded",
20        "format": "T",
21        "language": "fr",
22        "model": "A",
23        passOTP,
24        "password": secret,
25        "smoneyClientType": CLIENT_TYPE,
26        "userId": identification.identifier,
27        "version": "2.0"
28      },
29      method: "POST",
30      url: createRouteREST("LogonLight")
31    };
32  
33    const response = await fetcher(request);
34    const json = JSON.parse(response.content) as ServerError | {
35      LogonLightResult: {
36        Result: {
37          HasNewActu: boolean;
38          NSSE: null | string;
39          SessionId: string;
40          Tokens: null | Tokens;
41          UserStatus: ClientUserStatus;
42        };
43      };
44    };
45  
46    if ("Code" in json) {
47      if (json.Code === 571)
48        // For some reason, people might receive an SMS
49        // at this moment, but the URL in the SMS
50        // is completely unusable...
51        throw new NotRefreshableError();
52  
53      if (json.Code === 140 || json.Code === 570)
54        throw new ReauthenticateError();
55  
56      throw new Error(`${json.ErrorMessage} (${json.Code})`);
57    }
58  
59    const result = json.LogonLightResult.Result;
60    identification.sessionID = result.SessionId;
61  
62    if (result.NSSE) {
63      identification.nsse = result.NSSE;
64    }
65  
66    if (result.Tokens) {
67      identification.accessToken = result.Tokens.AccessToken;
68      identification.refreshToken = result.Tokens.RefreshToken;
69      identification.accessTokenExpiresIn = result.Tokens.ExpiresIn;
70    }
71  };