UNPKG

@etsoo/appscript

Version:

Applications shared TypeScript framework

328 lines (299 loc) 8.48 kB
import { IApiPayload } from "@etsoo/restclient"; import { IUser } from "../state/User"; import { BaseApi } from "./BaseApi"; import { ResultPayload } from "./dto/ResultPayload"; import { ActionResult, DataTypes, IActionResult } from "@etsoo/shared"; import { RefreshTokenProps, RefreshTokenResult } from "../app/IApp"; import { TokenInputRQ, TokenRQ } from "./rq/TokenRQ"; import { ApiRefreshTokenDto } from "./dto/ApiRefreshTokenDto"; import { GetLogInUrlRQ } from "./rq/GetLogInUrlRQ"; import { LoginInputAuthResult, LoginInputRQ, LoginRQ } from "./rq/LoginRQ"; import { LoginIdRQ } from "./rq/LoginIdRQ"; import { RefreshTokenRQ } from "./rq/RefreshTokenRQ"; import { ResetPasswordInputRQ, ResetPasswordRQ } from "./rq/ResetPasswordRQ"; import { SignoutRQ } from "./rq/SignoutRQ"; import { SwitchOrgRQ } from "./rq/SwitchOrgRQ"; import { AuthRequest } from "./rq/AuthRequest"; import { ChangePasswordRQ } from "./rq/ChangePasswordRQ"; import { CheckUserIdentifierRQ } from "./rq/CheckUserIdentifierRQ"; import { AdminSupportRQ } from "./rq/AdminSupportRQ"; /** * Authentication API */ export class AuthApi extends BaseApi { /** * Header token field name */ static HeaderTokenField = "Etsoo-Refresh-Token"; /** * Admin support * @param rq Request data * @param payload Payload * @returns Result */ adminSupport( rq: AdminSupportRQ, payload?: IApiPayload<IActionResult<LoginInputAuthResult>> ) { return this.api.post("Auth/AdminSupport", rq, payload); } /** * API refresh token * @param rq Request data * @param payload Payload * @returns Result */ apiRefreshToken(rq: TokenInputRQ, payload?: IApiPayload<ApiRefreshTokenDto>) { const data: TokenRQ = { ...rq, timeZone: this.app.getTimeZone() }; return this.api.put("Auth/ApiRefreshToken", data, payload); } /** * Authorization request * @param auth Authorization request data * @param payload Payload */ authRequest(auth: AuthRequest, payload?: IApiPayload<string>) { return this.api.post("Auth/AuthRequest", auth, payload); } /** * Change password * @param oldPassword Ole password * @param password New password * @param payload Payload * @returns Result */ changePassword( oldPassword: string, password: string, payload?: ResultPayload ) { const rq: ChangePasswordRQ = { appId: this.app.settings.appId, deviceId: this.app.deviceId, oldPassword: this.app.encrypt(this.app.hash(oldPassword)), password: this.app.encrypt(this.app.hash(password)) }; return this.api.put("Auth/ChangePassword", rq, payload); } /** * Check user identifier * @param type User identifier type * @param openid Open ID * @param payload Payload * @returns Result */ checkUserIdentifier( type: CheckUserIdentifierRQ["type"], openid: CheckUserIdentifierRQ["openid"], payload?: IApiPayload<DataTypes.TristateEnum> ) { const rq: CheckUserIdentifierRQ = { type, openid: this.app.encrypt(openid), deviceId: this.app.deviceId, region: this.app.region }; return this.api.post("Auth/CheckUserIdentifier", rq, payload); } /** * Exchange token * @param rq Request data * @param payload Payload * @returns Result */ exchangeToken(rq: TokenInputRQ, payload?: IApiPayload<ApiRefreshTokenDto>) { const data: TokenRQ = { ...rq, timeZone: this.app.getTimeZone() }; return this.api.put("Auth/ExchangeToken", data, payload); } /** * Get auth request * @param deviceId Device ID * @param payload Payload * @param apiHost API host * @returns Result */ getAuthRequest( deviceId?: string, payload?: IApiPayload<AuthRequest>, apiHost?: string ) { const rq: GetLogInUrlRQ = { region: this.app.region, device: deviceId ?? this.app.deviceId }; return this.api.post(`${apiHost ?? ""}Auth/GetAuthRequest`, rq, payload); } /** * Get log in url * @param deviceId Device ID * @param payload Payload * @param apiHost API host * @returns Result */ getLogInUrl( deviceId?: string, payload?: IApiPayload<string>, apiHost?: string ) { const rq: GetLogInUrlRQ = { region: this.app.region, device: deviceId ?? this.app.deviceId }; return this.api.get(`${apiHost ?? ""}Auth/GetLogInUrl`, rq, payload); } /** * Login * @param rq Request data * @param payload Payload * @param tokenKey Refresh token key * @returns Result */ async login<T extends IUser>( rq: LoginInputRQ, payload?: IApiPayload<IActionResult<T | LoginInputAuthResult>>, tokenKey?: string ): Promise< [IActionResult<T | LoginInputAuthResult> | undefined, string | null] > { // Default values payload ??= {}; tokenKey ??= AuthApi.HeaderTokenField; const data: LoginRQ = { ...rq, deviceId: this.app.deviceId, region: this.app.region, timeZone: this.app.getTimeZone() }; // Call the API const result = await this.api.post("Auth/Login", data, payload); // Get the refresh token const refreshToken = result?.ok ? this.app.getResponseToken(payload.response, tokenKey) : null; // Return the result return [result, refreshToken]; } /** * Login id check * @param id Check id * @param payload Payload * @returns Result */ loginId(id: string, payload?: ResultPayload) { const { deviceId, region } = this.app; id = this.app.encrypt(id); const rq: LoginIdRQ = { id, deviceId, region, timeZone: this.app.getTimeZone() }; return this.api.post("Auth/LoginId", rq, payload); } /** * Refresh token * @param props Props * @returns Result */ async refreshToken<R>( props: RefreshTokenProps ): Promise<RefreshTokenResult<R>> { // Destruct const { api = "Auth/RefreshToken", showLoading = false, token, tokenField = AuthApi.HeaderTokenField } = props ?? {}; // Check the token if (!token) { return { ok: false, type: "noData", field: "token", title: this.app.get("noData") }; } // Reqest data const rq: RefreshTokenRQ = { deviceId: this.app.deviceId, timeZone: this.app.getTimeZone() }; // Payload const payload: IApiPayload<R, any> = { // No loading bar needed to avoid screen flicks showLoading, config: { headers: { [tokenField]: token } }, onError: () => { // Prevent further processing return false; } }; // Call API const result = await this.api.put(api, rq, payload); if (result == null) { return this.api.lastError ? ActionResult.create(this.api.lastError) : { ok: false, type: "unknownError", field: "result", title: this.app.get("unknownError") }; } // Token const refreshToken = this.app.getResponseToken( payload.response, tokenField ); // Success return [refreshToken, result]; } /** * Reset password * @param rq Request data * @param payload Payload * @returns Result */ resetPassword(rq: ResetPasswordInputRQ, payload?: ResultPayload) { const data: ResetPasswordRQ = { ...rq, deviceId: this.app.deviceId, region: this.app.region, timezone: this.app.getTimeZone() }; return this.api.put("Auth/ResetPassword", data, payload); } /** * Signout * @param rq Request data * @param payload Payload * @returns Result */ signout(rq: SignoutRQ, payload?: ResultPayload) { return this.api.put("Auth/Signout", rq, payload); } /** * Switch organization * @param rq Request data * @param tokenKey Refresh token key * @param payload Payload */ async switchOrg<T extends IUser>( rq: SwitchOrgRQ, payload?: IApiPayload<IActionResult<T>>, tokenKey?: string ): Promise<[IActionResult<T> | undefined, string | null]> { // Default values payload ??= {}; tokenKey ??= AuthApi.HeaderTokenField; // Call the API const result = await this.api.put("Auth/SwitchOrg", rq, payload); // Get the refresh token const refreshToken = result?.ok ? this.app.getResponseToken(payload.response, tokenKey) : null; // Return the result return [result, refreshToken]; } }