@erpgulf/auth-sdk 0.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +357 -0
- package/dist/index.d.ts +125 -0
- package/dist/index.js +756 -0
- package/dist/index.js.map +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors/AuthError.ts","../src/form/encodeForm.ts","../src/master-token/MasterTokenManager.ts","../src/url/baseUrl.ts","../src/backend/frappe/endpoints.ts","../src/backend/frappe/schemas.ts","../src/backend/frappe/mappers.ts","../src/backend/frappe/FrappeAuthBackend.ts","../src/http/FetchTransport.ts","../src/flow/resolveAuthFlow.ts","../src/client/AuthClient.ts","../src/client/createAuthClient.ts"],"sourcesContent":["export type AuthErrorCode =\n | \"AUTHENTICATION_FAILED\"\n | \"INVALID_BASE_URL\"\n | \"INVALID_CLIENT_CONFIG\"\n | \"INVALID_MOBILE\"\n | \"INVALID_OR_EXPIRED_OTP\"\n | \"INVALID_PASSWORD\"\n | \"INVALID_RESPONSE\"\n | \"INVALID_SIGN_IN_INPUT\"\n | \"INVALID_SIGN_UP_INPUT\"\n | \"MASTER_TOKEN_FAILED\"\n | \"MASTER_TOKEN_REJECTED\"\n | \"NETWORK_ERROR\"\n | \"SERVER_ERROR\"\n | \"TIMEOUT\"\n | \"UNSUPPORTED_POLICY\";\n\nexport interface AuthErrorOptions {\n readonly cause?: unknown;\n readonly httpStatus?: number;\n readonly retryable?: boolean;\n}\n\nexport class AuthError extends Error {\n readonly code: AuthErrorCode;\n readonly httpStatus: number | undefined;\n readonly retryable: boolean;\n\n constructor(\n code: AuthErrorCode,\n message: string,\n options: AuthErrorOptions = {},\n ) {\n super(\n message,\n options.cause === undefined ? undefined : { cause: options.cause },\n );\n this.name = \"AuthError\";\n this.code = code;\n this.httpStatus = options.httpStatus;\n this.retryable = options.retryable ?? false;\n }\n}\n\nexport function isAuthError(error: unknown): error is AuthError {\n return error instanceof AuthError;\n}\n","export type FormValue = string | number | boolean | undefined;\n\nexport function encodeForm(\n values: Readonly<Record<string, FormValue>>,\n): string {\n const form = new URLSearchParams();\n\n for (const [key, value] of Object.entries(values)) {\n if (value !== undefined) {\n form.append(key, String(value));\n }\n }\n\n return form.toString();\n}\n","import type { MasterCredential } from \"../backend/types\";\n\nexport const MASTER_TOKEN_EXPIRY_SKEW_MS = 30_000;\n\nexport interface MasterTokenManagerOptions {\n readonly fetchCredential: () => Promise<MasterCredential>;\n readonly now?: () => number;\n readonly expirySkewMs?: number;\n}\n\nexport class MasterTokenManager {\n #credential: MasterCredential | undefined;\n #inFlight: Promise<MasterCredential> | undefined;\n private readonly expirySkewMs: number;\n private readonly fetchCredential: () => Promise<MasterCredential>;\n private readonly now: () => number;\n\n constructor(options: MasterTokenManagerOptions) {\n this.fetchCredential = options.fetchCredential;\n this.now = options.now ?? Date.now;\n this.expirySkewMs = options.expirySkewMs ?? MASTER_TOKEN_EXPIRY_SKEW_MS;\n }\n\n async getCredential(): Promise<MasterCredential> {\n if (this.isUsable(this.#credential)) {\n return this.#credential;\n }\n\n if (this.#inFlight !== undefined) {\n return this.#inFlight;\n }\n\n const acquisition = this.acquire();\n this.#inFlight = acquisition;\n\n try {\n return await acquisition;\n } finally {\n if (this.#inFlight === acquisition) {\n this.#inFlight = undefined;\n }\n }\n }\n\n invalidate(expectedAccessToken?: string): void {\n if (\n expectedAccessToken === undefined ||\n this.#credential?.accessToken === expectedAccessToken\n ) {\n this.#credential = undefined;\n }\n }\n\n private async acquire(): Promise<MasterCredential> {\n const credential = await this.fetchCredential();\n this.#credential = credential;\n return credential;\n }\n\n private isUsable(\n credential: MasterCredential | undefined,\n ): credential is MasterCredential {\n return (\n credential !== undefined &&\n this.now() < credential.expiresAt - this.expirySkewMs\n );\n }\n}\n","import { AuthError } from \"../errors/AuthError\";\n\nexport interface NormalizeBaseUrlOptions {\n readonly allowInsecureHttp?: boolean;\n}\n\nexport function normalizeBaseUrl(\n input: string,\n options: NormalizeBaseUrlOptions = {},\n): string {\n const trimmed = input.trim();\n let url: URL;\n\n try {\n url = new URL(trimmed);\n } catch {\n throw invalidBaseUrl(\"Base URL must be a valid absolute URL.\");\n }\n\n if (url.protocol !== \"https:\" && url.protocol !== \"http:\") {\n throw invalidBaseUrl(\"Base URL must use the HTTPS or HTTP protocol.\");\n }\n\n if (url.protocol === \"http:\" && options.allowInsecureHttp !== true) {\n throw invalidBaseUrl(\n \"HTTP base URLs require allowInsecureHttp: true and should only be used for development.\",\n );\n }\n\n if (url.hostname.length === 0) {\n throw invalidBaseUrl(\"Base URL must include a hostname.\");\n }\n\n if (url.username.length > 0 || url.password.length > 0) {\n throw invalidBaseUrl(\"Base URL must not contain embedded credentials.\");\n }\n\n if (url.hash.length > 0) {\n throw invalidBaseUrl(\"Base URL must not contain a fragment.\");\n }\n\n if (url.search.length > 0) {\n throw invalidBaseUrl(\"Base URL must not contain a query string.\");\n }\n\n if (url.pathname !== \"/\") {\n throw invalidBaseUrl(\"Base URL must not contain a path.\");\n }\n\n return url.origin;\n}\n\nexport function joinUrl(baseUrl: string, endpoint: string): string {\n const normalizedEndpoint = endpoint.replace(/^\\/+/, \"\");\n\n if (normalizedEndpoint.length === 0) {\n return baseUrl;\n }\n\n return `${baseUrl}/${normalizedEndpoint}`;\n}\n\nfunction invalidBaseUrl(message: string): AuthError {\n return new AuthError(\"INVALID_BASE_URL\", message);\n}\n","export const AUTH_ENDPOINTS = {\n masterToken: \"/api/method/employee_app.authentication.master_token\",\n loginPolicy:\n \"/api/method/employee_app.authentication.get_employee_login_policy\",\n sendOtp: \"/api/method/employee_app.authentication.generate_and_send_otp\",\n signUp: \"/api/method/employee_app.authentication.sign_up_api\",\n signIn: \"/api/method/employee_app.sign_in.sign_in_api\",\n} as const;\n","import { z } from \"zod\";\n\nexport const backendPolicyValueSchema = z.enum([\"Mandatory\", \"Optional\", \"No\"]);\n\nconst tokenSchema = z.object({\n access_token: z.string().min(1),\n expires_in: z.number().int().positive(),\n token_type: z.string().min(1),\n scope: z.string(),\n refresh_token: z.string().min(1),\n});\n\nconst employeeSchema = z.object({\n id: z.string().min(1),\n employee_name: z.string().min(1),\n phone: z.string().min(1),\n email: z.string().nullable(),\n});\n\nexport const masterTokenResponseSchema = z.object({\n data: tokenSchema.extend({\n // This value will enter an HTTP header. Reject whitespace, controls and\n // non-ASCII values rather than letting fetch echo them in an exception.\n access_token: z.string().regex(/^[\\x21-\\x7e]+$/u),\n }),\n});\n\nexport const loginPolicyResponseSchema = z.object({\n status: z.literal(\"success\"),\n employee_id: z.string().min(1),\n policy: z.object({\n password_policy: backendPolicyValueSchema,\n otp_policy: backendPolicyValueSchema,\n }),\n employee_has_existing_password: z.boolean(),\n employee_has_signed_up: z.boolean(),\n});\n\nexport const sendOtpResponseSchema = z.object({\n status: z.literal(\"success\"),\n message: z.string(),\n otp_expires_in: z.number().int().positive(),\n});\n\nexport const signUpResponseSchema = z.object({\n status: z.literal(\"success\"),\n data: z.object({\n token: tokenSchema,\n employee: employeeSchema,\n time: z.string().min(1),\n }),\n});\n\nexport const signInResponseSchema = z.object({\n status: z.literal(\"success\"),\n data: z.object({\n token: tokenSchema,\n employee: employeeSchema,\n password_policy: backendPolicyValueSchema,\n otp_policy: backendPolicyValueSchema,\n time: z.string().min(1),\n }),\n});\n\nexport const backendErrorResponseSchema = z.object({\n status: z.literal(\"error\"),\n message: z.string(),\n});\n\n// Evidence: origin/expo-auth-starter at fd8b565, auth/api/auth-client.ts.\n// Do not generalize this middleware signal to all HTTP 401/403 responses.\nexport const masterAuthenticationErrorSchema = z.object({\n exc_type: z.literal(\"AuthenticationError\"),\n});\n\nexport const businessErrorMarkerSchema = z.object({\n status: z.literal(\"error\"),\n});\n\nexport type BackendPolicyValue = z.infer<typeof backendPolicyValueSchema>;\nexport type MasterTokenResponse = z.infer<typeof masterTokenResponseSchema>;\nexport type LoginPolicyResponse = z.infer<typeof loginPolicyResponseSchema>;\nexport type SendOtpResponse = z.infer<typeof sendOtpResponseSchema>;\nexport type SignUpResponse = z.infer<typeof signUpResponseSchema>;\nexport type SignInResponse = z.infer<typeof signInResponseSchema>;\n","import { AuthError } from \"../../errors/AuthError\";\nimport type { AuthPolicy, OtpPolicy, PasswordPolicy } from \"../../policy/types\";\nimport type {\n AuthEmployee,\n AuthResult,\n AuthToken,\n MasterCredential,\n SendOtpResult,\n SignInResult,\n} from \"../types\";\nimport {\n loginPolicyResponseSchema,\n masterTokenResponseSchema,\n sendOtpResponseSchema,\n signInResponseSchema,\n signUpResponseSchema,\n type BackendPolicyValue,\n type SignInResponse,\n type SignUpResponse,\n} from \"./schemas\";\n\nexport function mapMasterCredential(\n value: unknown,\n now: number,\n): MasterCredential {\n const response = parseConfirmedResponse(\n masterTokenResponseSchema,\n value,\n \"master-token\",\n );\n\n return {\n accessToken: response.data.access_token,\n expiresIn: response.data.expires_in,\n expiresAt: now + response.data.expires_in * 1_000,\n tokenType: normalizeTokenType(response.data.token_type),\n scope: response.data.scope,\n };\n}\n\nexport function mapLoginPolicy(value: unknown): AuthPolicy {\n const response = parseConfirmedResponse(\n loginPolicyResponseSchema,\n value,\n \"login-policy\",\n );\n\n return {\n employeeId: response.employee_id,\n employeeHasExistingPassword: response.employee_has_existing_password,\n employeeHasSignedUp: response.employee_has_signed_up,\n passwordPolicy: mapPasswordPolicy(response.policy.password_policy),\n otpPolicy: mapOtpPolicy(response.policy.otp_policy),\n };\n}\n\nexport function mapSendOtpResult(value: unknown): SendOtpResult {\n const response = parseConfirmedResponse(\n sendOtpResponseSchema,\n value,\n \"send-OTP\",\n );\n\n return { expiresIn: response.otp_expires_in };\n}\n\nexport function mapSignUpResult(value: unknown): AuthResult {\n const response = parseConfirmedResponse(\n signUpResponseSchema,\n value,\n \"sign-up\",\n );\n\n return mapBaseAuthResult(response);\n}\n\nexport function mapSignInResult(value: unknown): SignInResult {\n const response = parseConfirmedResponse(\n signInResponseSchema,\n value,\n \"sign-in\",\n );\n\n return {\n ...mapBaseAuthResult(response),\n passwordPolicy: mapPasswordPolicy(response.data.password_policy),\n otpPolicy: mapOtpPolicy(response.data.otp_policy),\n };\n}\n\nfunction mapBaseAuthResult(\n response: SignUpResponse | SignInResponse,\n): AuthResult {\n return {\n token: mapToken(response.data.token),\n employee: mapEmployee(response.data.employee),\n authenticatedAt: response.data.time,\n };\n}\n\nfunction mapToken(token: SignUpResponse[\"data\"][\"token\"]): AuthToken {\n return {\n accessToken: token.access_token,\n refreshToken: token.refresh_token,\n expiresIn: token.expires_in,\n tokenType: normalizeTokenType(token.token_type),\n scope: token.scope,\n };\n}\n\nfunction mapEmployee(\n employee: SignUpResponse[\"data\"][\"employee\"],\n): AuthEmployee {\n return {\n id: employee.id,\n name: employee.employee_name,\n phone: employee.phone,\n email: employee.email,\n };\n}\n\nfunction normalizeTokenType(value: string): string {\n return value.toLowerCase() === \"bearer\" ? \"Bearer\" : value;\n}\n\nfunction mapPasswordPolicy(value: BackendPolicyValue): PasswordPolicy {\n return mapPolicy(value);\n}\n\nfunction mapOtpPolicy(value: BackendPolicyValue): OtpPolicy {\n return mapPolicy(value);\n}\n\nfunction mapPolicy(\n value: BackendPolicyValue,\n): \"required\" | \"optional\" | \"disabled\" {\n switch (value) {\n case \"Mandatory\":\n return \"required\";\n case \"Optional\":\n return \"optional\";\n case \"No\":\n return \"disabled\";\n }\n}\n\nfunction parseConfirmedResponse<T>(\n schema: {\n safeParse(value: unknown):\n | { success: true; data: T }\n | {\n success: false;\n error: {\n issues: readonly {\n readonly code: string;\n readonly path: readonly PropertyKey[];\n }[];\n };\n };\n },\n value: unknown,\n operation: string,\n): T {\n const result = schema.safeParse(value);\n\n if (result.success) {\n return result.data;\n }\n\n const unsupportedPolicy = result.error.issues.some(\n (issue) =>\n issue.code === \"invalid_value\" &&\n (issue.path.at(-1) === \"password_policy\" ||\n issue.path.at(-1) === \"otp_policy\"),\n );\n\n if (unsupportedPolicy) {\n throw new AuthError(\n \"UNSUPPORTED_POLICY\",\n \"Backend returned an unsupported authentication policy.\",\n );\n }\n\n throw new AuthError(\n \"INVALID_RESPONSE\",\n `Backend returned a malformed ${operation} response.`,\n );\n}\n","import { AuthError, isAuthError } from \"../../errors/AuthError\";\nimport { encodeForm } from \"../../form/encodeForm\";\nimport type {\n HttpRequest,\n HttpResponse,\n HttpTransport,\n} from \"../../http/types\";\nimport { MasterTokenManager } from \"../../master-token/MasterTokenManager\";\nimport type { AuthPolicy } from \"../../policy/types\";\nimport { joinUrl } from \"../../url/baseUrl\";\nimport type {\n AuthBackend,\n AuthResult,\n GetLoginPolicyInput,\n MasterCredential,\n SendOtpInput,\n SendOtpResult,\n SignInInput,\n SignInResult,\n SignUpInput,\n} from \"../types\";\nimport { AUTH_ENDPOINTS } from \"./endpoints\";\nimport {\n mapLoginPolicy,\n mapMasterCredential,\n mapSendOtpResult,\n mapSignInResult,\n mapSignUpResult,\n} from \"./mappers\";\nimport {\n backendErrorResponseSchema,\n businessErrorMarkerSchema,\n masterAuthenticationErrorSchema,\n} from \"./schemas\";\n\nconst FORM_CONTENT_TYPE = \"application/x-www-form-urlencoded\";\n\nexport interface FrappeAuthBackendOptions {\n readonly baseUrl: string;\n readonly transport: HttpTransport;\n readonly timeoutMs: number;\n readonly appId?: string;\n readonly appVersion?: string;\n readonly now?: () => number;\n}\n\nexport class FrappeAuthBackend implements AuthBackend {\n private readonly baseUrl: string;\n private readonly defaultHeaders: Readonly<Record<string, string>>;\n readonly #masterTokens: MasterTokenManager;\n private readonly now: () => number;\n private readonly timeoutMs: number;\n readonly #transport: HttpTransport;\n\n constructor(options: FrappeAuthBackendOptions) {\n this.baseUrl = options.baseUrl;\n this.#transport = options.transport;\n this.timeoutMs = options.timeoutMs;\n this.now = options.now ?? Date.now;\n this.defaultHeaders = createMetadataHeaders(options);\n this.#masterTokens = new MasterTokenManager({\n fetchCredential: () => this.fetchMasterCredential(),\n now: this.now,\n });\n }\n\n async getLoginPolicy(input: GetLoginPolicyInput): Promise<AuthPolicy> {\n const query = encodeForm({ mobile: input.mobileNumber });\n const response = await this.requestWithMasterAuth(\n (accessToken) => ({\n method: \"GET\",\n url: `${this.endpoint(AUTH_ENDPOINTS.loginPolicy)}?${query}`,\n headers: this.formHeaders(accessToken),\n timeoutMs: this.timeoutMs,\n }),\n false,\n );\n ensureSuccess(response, \"login-policy\", false);\n return mapLoginPolicy(response.body);\n }\n\n async sendOtp(input: SendOtpInput): Promise<SendOtpResult> {\n const response = await this.requestWithMasterAuth(\n (accessToken) => ({\n method: \"POST\",\n url: this.endpoint(AUTH_ENDPOINTS.sendOtp),\n headers: this.formHeaders(accessToken),\n body: encodeForm({ mobile_no: input.mobileNumber }),\n timeoutMs: this.timeoutMs,\n }),\n true,\n );\n ensureSuccess(response, \"send-OTP\", true);\n return mapSendOtpResult(response.body);\n }\n\n async signUp(input: SignUpInput): Promise<AuthResult> {\n const response = await this.requestTransport(\n {\n method: \"POST\",\n url: this.endpoint(AUTH_ENDPOINTS.signUp),\n headers: this.formHeaders(),\n body: encodeForm({\n mobile_no: input.mobileNumber,\n otp: input.otp,\n password: input.password,\n }),\n timeoutMs: this.timeoutMs,\n },\n true,\n );\n ensureSuccess(response, \"sign-up\", true);\n return mapSignUpResult(response.body);\n }\n\n async signIn(input: SignInInput): Promise<SignInResult> {\n const response = await this.requestWithMasterAuth(\n (accessToken) => ({\n method: \"POST\",\n url: this.endpoint(AUTH_ENDPOINTS.signIn),\n headers: this.formHeaders(accessToken),\n body: encodeForm({\n mobile_no: input.mobileNumber,\n otp: input.otp,\n password: input.password,\n }),\n timeoutMs: this.timeoutMs,\n }),\n true,\n );\n\n // Infrastructure failures must not be presented as incorrect credentials,\n // even if their body happens to resemble a business-error envelope.\n if (response.status >= 500) {\n ensureSuccess(response, \"sign-in\", true);\n }\n\n const backendError = backendErrorResponseSchema.safeParse(response.body);\n if (backendError.success) {\n throw mapSignInError(backendError.data.message, response.status);\n }\n\n ensureSuccess(response, \"sign-in\", true);\n return mapSignInResult(response.body);\n }\n\n private endpoint(path: string): string {\n return joinUrl(this.baseUrl, path);\n }\n\n private async fetchMasterCredential(): Promise<MasterCredential> {\n const response = await this.requestTransport(\n {\n method: \"GET\",\n url: this.endpoint(AUTH_ENDPOINTS.masterToken),\n headers: this.defaultHeaders,\n timeoutMs: this.timeoutMs,\n },\n false,\n );\n\n if (response.status < 200 || response.status >= 300) {\n throw new AuthError(\n \"MASTER_TOKEN_FAILED\",\n \"Unable to acquire the master authentication token.\",\n {\n httpStatus: response.status,\n retryable: response.status >= 500,\n },\n );\n }\n\n try {\n return mapMasterCredential(response.body, this.now());\n } catch (error: unknown) {\n if (isAuthError(error) && error.code === \"INVALID_RESPONSE\") {\n throw new AuthError(\n \"MASTER_TOKEN_FAILED\",\n \"Backend returned a malformed master-token response.\",\n );\n }\n\n throw error;\n }\n }\n\n private formHeaders(accessToken?: string): Readonly<Record<string, string>> {\n return accessToken === undefined\n ? { ...this.defaultHeaders, \"Content-Type\": FORM_CONTENT_TYPE }\n : {\n ...this.defaultHeaders,\n \"Content-Type\": FORM_CONTENT_TYPE,\n Authorization: `Bearer ${accessToken}`,\n };\n }\n\n private async requestWithMasterAuth(\n buildRequest: (accessToken: string) => HttpRequest,\n replayUnsafe: boolean,\n ): Promise<HttpResponse> {\n const firstCredential = await this.#masterTokens.getCredential();\n const firstResponse = await this.requestTransport(\n buildRequest(firstCredential.accessToken),\n replayUnsafe,\n );\n\n if (!isMasterRejection(firstResponse)) {\n return firstResponse;\n }\n\n this.#masterTokens.invalidate(firstCredential.accessToken);\n const replacement = await this.#masterTokens.getCredential();\n const retryResponse = await this.requestTransport(\n buildRequest(replacement.accessToken),\n replayUnsafe,\n );\n\n if (isMasterRejection(retryResponse)) {\n this.#masterTokens.invalidate(replacement.accessToken);\n throw new AuthError(\n \"MASTER_TOKEN_REJECTED\",\n \"The server rejected master authentication.\",\n { httpStatus: retryResponse.status },\n );\n }\n\n return retryResponse;\n }\n\n private async requestTransport(\n request: HttpRequest,\n replayUnsafe: boolean,\n ): Promise<HttpResponse> {\n try {\n return await this.#transport.request(request);\n } catch (error: unknown) {\n // A transport returns HTTP errors as responses; thrown values indicate\n // transport failure. Custom transports may attach sensitive request data.\n const timedOut = isAuthError(error) && error.code === \"TIMEOUT\";\n throw new AuthError(\n timedOut ? \"TIMEOUT\" : \"NETWORK_ERROR\",\n timedOut\n ? \"Authentication request timed out.\"\n : \"Authentication request could not reach the server.\",\n { retryable: !replayUnsafe },\n );\n }\n }\n}\n\nfunction createMetadataHeaders(\n options: FrappeAuthBackendOptions,\n): Readonly<Record<string, string>> {\n const headers: Record<string, string> = {};\n\n if (options.appId !== undefined) {\n headers[\"X-ERPGulf-App-Id\"] = options.appId;\n }\n\n if (options.appVersion !== undefined) {\n headers[\"X-ERPGulf-App-Version\"] = options.appVersion;\n }\n\n return headers;\n}\n\nfunction isMasterRejection(response: HttpResponse): boolean {\n return (\n response.status === 401 &&\n !businessErrorMarkerSchema.safeParse(response.body).success &&\n masterAuthenticationErrorSchema.safeParse(response.body).success\n );\n}\n\nfunction ensureSuccess(\n response: HttpResponse,\n operation: string,\n replayUnsafe: boolean,\n): void {\n if (response.status >= 200 && response.status < 300) {\n return;\n }\n\n throw new AuthError(\"SERVER_ERROR\", `The ${operation} request failed.`, {\n httpStatus: response.status,\n retryable: !replayUnsafe && response.status >= 500,\n });\n}\n\nfunction mapSignInError(message: string, httpStatus: number): AuthError {\n if (message === \"Invalid or expired OTP\") {\n return new AuthError(\n \"INVALID_OR_EXPIRED_OTP\",\n \"The OTP is invalid or expired.\",\n { httpStatus },\n );\n }\n\n if (message === \"Invalid password\") {\n return new AuthError(\"INVALID_PASSWORD\", \"The password is invalid.\", {\n httpStatus,\n });\n }\n\n return new AuthError(\n \"AUTHENTICATION_FAILED\",\n \"Authentication was not successful.\",\n { httpStatus },\n );\n}\n","import { AuthError } from \"../errors/AuthError\";\nimport type { HttpRequest, HttpResponse, HttpTransport } from \"./types\";\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\nexport class FetchTransport implements HttpTransport {\n async request(request: HttpRequest): Promise<HttpResponse> {\n const timeoutMs = request.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const response = await fetch(request.url, {\n method: request.method,\n signal: controller.signal,\n redirect: \"error\",\n cache: \"no-store\",\n credentials: \"omit\",\n ...(request.headers === undefined ? {} : { headers: request.headers }),\n ...(request.body === undefined ? {} : { body: request.body }),\n });\n\n return {\n status: response.status,\n body: await parseResponseBody(response),\n };\n } catch {\n if (controller.signal.aborted) {\n throw new AuthError(\"TIMEOUT\", \"Authentication request timed out.\", {\n retryable: true,\n });\n }\n\n // Native and injected fetch errors can contain headers or request bodies.\n // Never attach them to a consumer-visible cause chain.\n throw new AuthError(\n \"NETWORK_ERROR\",\n \"Authentication request could not reach the server.\",\n { retryable: true },\n );\n } finally {\n clearTimeout(timeout);\n }\n }\n}\n\nasync function parseResponseBody(response: Response): Promise<unknown> {\n const text = await response.text();\n\n if (text.length === 0) {\n return undefined;\n }\n\n try {\n return JSON.parse(text) as unknown;\n } catch {\n return text;\n }\n}\n","import { AuthError } from \"../errors/AuthError\";\nimport type { AuthPolicy } from \"../policy/types\";\nimport type {\n AuthAction,\n AuthFlow,\n AuthNextStep,\n CredentialName,\n} from \"./types\";\n\nexport function resolveAuthFlow(policy: AuthPolicy): AuthFlow {\n if (!policy.employeeHasSignedUp && policy.employeeHasExistingPassword) {\n throw unsupportedPolicy(\n \"An employee who has not signed up cannot have an existing password.\",\n );\n }\n\n if (policy.passwordPolicy === \"disabled\" && policy.otpPolicy === \"disabled\") {\n throw unsupportedPolicy(\n \"Authentication policy disables both password and OTP credentials.\",\n );\n }\n\n const action: AuthAction = policy.employeeHasSignedUp ? \"SIGN_IN\" : \"SIGN_UP\";\n const atLeastOneOf = resolveAtLeastOneOf(policy);\n\n return {\n action,\n nextStep: resolveNextStep(policy),\n credentials: {\n password: policy.passwordPolicy,\n otp: policy.otpPolicy,\n atLeastOneOf,\n },\n policy,\n };\n}\n\nfunction resolveAtLeastOneOf(policy: AuthPolicy): readonly CredentialName[] {\n if (policy.passwordPolicy === \"required\" || policy.otpPolicy === \"required\") {\n return [];\n }\n\n const credentials: CredentialName[] = [];\n\n if (policy.passwordPolicy === \"optional\") {\n credentials.push(\"password\");\n }\n\n if (policy.otpPolicy === \"optional\") {\n credentials.push(\"otp\");\n }\n\n return credentials;\n}\n\nfunction resolveNextStep(policy: AuthPolicy): AuthNextStep {\n if (policy.passwordPolicy === \"required\" && policy.otpPolicy === \"required\") {\n return \"ENTER_PASSWORD_AND_OTP\";\n }\n\n if (policy.passwordPolicy === \"required\") {\n return policy.employeeHasExistingPassword\n ? \"ENTER_PASSWORD\"\n : \"CREATE_PASSWORD\";\n }\n\n if (policy.otpPolicy === \"required\") {\n return \"ENTER_OTP\";\n }\n\n if (policy.passwordPolicy === \"optional\" && policy.otpPolicy === \"optional\") {\n return \"CHOOSE_PASSWORD_OR_OTP\";\n }\n\n return policy.passwordPolicy === \"optional\"\n ? policy.employeeHasExistingPassword\n ? \"ENTER_PASSWORD\"\n : \"CREATE_PASSWORD\"\n : \"ENTER_OTP\";\n}\n\nfunction unsupportedPolicy(message: string): AuthError {\n return new AuthError(\"UNSUPPORTED_POLICY\", message);\n}\n","import type {\n AuthBackend,\n AuthResult,\n GetLoginPolicyInput,\n SendOtpInput,\n SendOtpResult,\n SignInInput,\n SignInResult,\n SignUpInput,\n} from \"../backend/types\";\nimport { AuthError } from \"../errors/AuthError\";\nimport { resolveAuthFlow } from \"../flow/resolveAuthFlow\";\nimport type { AuthFlow } from \"../flow/types\";\nimport type { AuthPolicy } from \"../policy/types\";\nimport type { AuthClient } from \"./types\";\n\nexport class DefaultAuthClient implements AuthClient {\n readonly #backend: AuthBackend;\n\n constructor(backend: AuthBackend) {\n this.#backend = backend;\n }\n\n async begin(input: GetLoginPolicyInput): Promise<AuthFlow> {\n const policy = await this.getLoginPolicy(input);\n return resolveAuthFlow(policy);\n }\n\n async getLoginPolicy(input: GetLoginPolicyInput): Promise<AuthPolicy> {\n return await this.#backend.getLoginPolicy({\n mobileNumber: validateMobile(input.mobileNumber),\n });\n }\n\n async sendOtp(input: SendOtpInput): Promise<SendOtpResult> {\n return await this.#backend.sendOtp({\n mobileNumber: validateMobile(input.mobileNumber),\n });\n }\n\n async signUp(input: SignUpInput): Promise<AuthResult> {\n const otp = validateOptionalCredential(input.otp, \"otp\", \"sign-up\");\n const password = validateOptionalCredential(\n input.password,\n \"password\",\n \"sign-up\",\n );\n\n if (otp === undefined && password === undefined) {\n throw new AuthError(\n \"INVALID_SIGN_UP_INPUT\",\n \"Sign-up requires an OTP, a password, or both according to policy.\",\n );\n }\n\n return await this.#backend.signUp({\n mobileNumber: validateMobile(input.mobileNumber),\n ...(otp === undefined ? {} : { otp }),\n ...(password === undefined ? {} : { password }),\n });\n }\n\n async signIn(input: SignInInput): Promise<SignInResult> {\n const otp = validateOptionalCredential(input.otp, \"otp\", \"sign-in\");\n const password = validateOptionalCredential(\n input.password,\n \"password\",\n \"sign-in\",\n );\n\n if (otp === undefined && password === undefined) {\n throw new AuthError(\n \"INVALID_SIGN_IN_INPUT\",\n \"Sign-in requires an OTP, a password, or both.\",\n );\n }\n\n return await this.#backend.signIn({\n mobileNumber: validateMobile(input.mobileNumber),\n ...(otp === undefined ? {} : { otp }),\n ...(password === undefined ? {} : { password }),\n });\n }\n}\n\nfunction validateMobile(mobileNumber: string): string {\n const normalized = mobileNumber.trim();\n\n if (normalized.length === 0) {\n throw new AuthError(\"INVALID_MOBILE\", \"Mobile number must not be empty.\");\n }\n\n return normalized;\n}\n\nfunction validateOptionalCredential(\n value: string | undefined,\n name: \"otp\" | \"password\",\n operation: \"sign-in\" | \"sign-up\",\n): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n if (value.length === 0) {\n throw new AuthError(\n operation === \"sign-in\"\n ? \"INVALID_SIGN_IN_INPUT\"\n : \"INVALID_SIGN_UP_INPUT\",\n `${name === \"otp\" ? \"OTP\" : \"Password\"} must not be empty when provided.`,\n );\n }\n\n return value;\n}\n","import { FrappeAuthBackend } from \"../backend/frappe/FrappeAuthBackend\";\nimport { AuthError } from \"../errors/AuthError\";\nimport { FetchTransport } from \"../http/FetchTransport\";\nimport { normalizeBaseUrl } from \"../url/baseUrl\";\nimport { DefaultAuthClient } from \"./AuthClient\";\nimport type { AuthClient, AuthClientConfig } from \"./types\";\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\nexport function createAuthClient(config: AuthClientConfig): AuthClient {\n const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n validateTimeout(timeoutMs);\n validateMetadata(config.metadata?.appId, \"appId\");\n validateMetadata(config.metadata?.appVersion, \"appVersion\");\n\n const backend = new FrappeAuthBackend({\n baseUrl: normalizeBaseUrl(\n config.baseUrl,\n config.allowInsecureHttp === undefined\n ? {}\n : { allowInsecureHttp: config.allowInsecureHttp },\n ),\n transport: config.transport ?? new FetchTransport(),\n timeoutMs,\n ...(config.metadata?.appId === undefined\n ? {}\n : { appId: config.metadata.appId }),\n ...(config.metadata?.appVersion === undefined\n ? {}\n : { appVersion: config.metadata.appVersion }),\n });\n\n return new DefaultAuthClient(backend);\n}\n\nfunction validateTimeout(timeoutMs: number): void {\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n throw new AuthError(\n \"INVALID_CLIENT_CONFIG\",\n \"timeoutMs must be a positive finite number.\",\n );\n }\n}\n\nfunction validateMetadata(value: string | undefined, name: string): void {\n if (value !== undefined && (value.length === 0 || /[\\r\\n]/u.test(value))) {\n throw new AuthError(\n \"INVALID_CLIENT_CONFIG\",\n `${name} must be non-empty and must not contain line breaks.`,\n );\n }\n}\n"],"mappings":"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","names":["unsupportedPolicy","DEFAULT_TIMEOUT_MS"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@erpgulf/auth-sdk",
|
|
3
|
+
"version": "0.1.0-beta.1",
|
|
4
|
+
"description": "Framework-independent authentication flow SDK for ERPGulf applications",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md"
|
|
10
|
+
],
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"main": "./dist/index.js",
|
|
18
|
+
"module": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=20"
|
|
22
|
+
},
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "https://github.com/ERPGulf/ui-shared-code.git",
|
|
26
|
+
"directory": "packages/erpgulf-auth-sdk"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public",
|
|
30
|
+
"registry": "https://registry.npmjs.org",
|
|
31
|
+
"tag": "beta"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"zod": "4.1.5"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsup src/index.ts --format esm --dts --clean --sourcemap",
|
|
38
|
+
"lint": "eslint .",
|
|
39
|
+
"test": "vitest run",
|
|
40
|
+
"typecheck": "tsc --noEmit"
|
|
41
|
+
}
|
|
42
|
+
}
|