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 };