@alore/auth-react-sdk
Advanced tools
+0
-2
@@ -23,3 +23,2 @@ export type FetchWithProgressiveBackoffConfig = { | ||
| * @property enableWalletCreation - Optional boolean to enable wallet creation. | ||
| * @property allowedEmailDomains - Optional allowed email domain(s). If provided, authentication will only allow emails from these domains. Accepts a single string (e.g., 'bealore.com' or '@bealore.com') or an array of strings. | ||
| */ | ||
@@ -42,3 +41,2 @@ export interface AuthProviderConfig { | ||
| firebaseCompatible?: boolean; | ||
| allowedEmailDomains?: string | string[]; | ||
| } | ||
@@ -45,0 +43,0 @@ export interface AuthMachineContext { |
@@ -8,3 +8,2 @@ import type { AuthMachineContext, AuthProviderConfig, FetchWithProgressiveBackoffConfig, ForgeData } from '../types'; | ||
| services: { | ||
| isEmailAllowed: (context: AuthMachineContext, email?: string | null) => boolean; | ||
| healthCheck: () => Promise<{ | ||
@@ -20,7 +19,3 @@ data: boolean; | ||
| salt: string; | ||
| error?: undefined; | ||
| } | { | ||
| error: string; | ||
| salt?: undefined; | ||
| }>; | ||
| } | undefined>; | ||
| verifyEmail: (context: AuthMachineContext, event: { | ||
@@ -31,3 +26,3 @@ type: 'VERIFY_EMAIL'; | ||
| }; | ||
| }) => Promise<{}>; | ||
| }) => Promise<{} | undefined>; | ||
| completeRegistration: (context: AuthMachineContext, event: { | ||
@@ -48,7 +43,3 @@ type: 'COMPLETE_REGISTRATION'; | ||
| }; | ||
| }) => Promise<{ | ||
| error?: undefined; | ||
| } | { | ||
| error: string; | ||
| }>; | ||
| }) => Promise<{}>; | ||
| sendConfirmationEmail: (context: AuthMachineContext, event: { | ||
@@ -75,8 +66,3 @@ type: 'RESEND_CODE'; | ||
| sessionId: any; | ||
| error?: undefined; | ||
| } | { | ||
| error: string; | ||
| salt?: undefined; | ||
| sessionId?: undefined; | ||
| }>; | ||
| } | undefined>; | ||
| sendCode: (context: AuthMachineContext, event: { | ||
@@ -87,7 +73,3 @@ type: 'SEND_CODE'; | ||
| }; | ||
| }) => Promise<{ | ||
| error: string; | ||
| } | { | ||
| error?: undefined; | ||
| }>; | ||
| }) => Promise<{}>; | ||
| verifyLogin: (context: AuthMachineContext, event: { | ||
@@ -274,4 +256,6 @@ type: 'VERIFY_LOGIN'; | ||
| fetchWithProgressiveBackoff(url: RequestInfo | URL, options?: RequestInit, config?: FetchWithProgressiveBackoffConfig): Promise<Response>; | ||
| private parseErrorResponse; | ||
| private throwParsedResponseError; | ||
| private verifyBackendStatus; | ||
| private extractErrorInfo; | ||
| } |
+58
-77
@@ -16,24 +16,2 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
| this.services = { | ||
| // Utility to check if an email is allowed based on allowedEmailDomains config | ||
| isEmailAllowed: (context, email) => { | ||
| var _a; | ||
| const allowedConf = (_a = context.authProviderConfigs) === null || _a === void 0 ? void 0 : _a.allowedEmailDomains; | ||
| const allowedList = | ||
| // eslint-disable-next-line no-nested-ternary | ||
| typeof allowedConf === 'string' | ||
| ? [allowedConf] | ||
| : Array.isArray(allowedConf) | ||
| ? allowedConf | ||
| : []; | ||
| if (allowedList.length === 0) | ||
| return true; | ||
| if (!email) | ||
| return false; | ||
| const domain = (email.split('@')[1] || '').toLowerCase(); | ||
| // Allow items like '@bealore.com' or 'bealore.com' | ||
| return allowedList.some((d) => { | ||
| const normalized = d.startsWith('@') ? d.slice(1) : d; | ||
| return domain === normalized.toLowerCase(); | ||
| }); | ||
| }, | ||
| healthCheck: () => __awaiter(this, void 0, void 0, function* () { | ||
@@ -51,5 +29,2 @@ try { | ||
| const { email } = event.payload; | ||
| if (!this.services.isEmailAllowed(context, email)) { | ||
| throw new AloreAuthError(ErrorTypes.EMAIL_DOMAIN_NOT_ALLOWED, 'Email domain not allowed', 400); | ||
| } | ||
| const { credentialEmail } = context; | ||
@@ -65,3 +40,4 @@ const response = yield this.fetchWithProgressiveBackoff(`/auth/v1/salt/${email || credentialEmail}`, { | ||
| } | ||
| return { error: response === null || response === void 0 ? void 0 : response.statusText }; | ||
| // Propagate parsed error so machine receives full payload as event.data | ||
| yield this.throwParsedResponseError(response); | ||
| }), | ||
@@ -83,10 +59,6 @@ verifyEmail: (context, event) => __awaiter(this, void 0, void 0, function* () { | ||
| } | ||
| const data = yield response.json(); | ||
| throw new Error((data === null || data === void 0 ? void 0 : data.message) || (data === null || data === void 0 ? void 0 : data.error) || data); | ||
| yield this.throwParsedResponseError(response); | ||
| }), | ||
| completeRegistration: (context, event) => __awaiter(this, void 0, void 0, function* () { | ||
| const { email, nickname, passwordHash, device } = event.payload; | ||
| if (!this.services.isEmailAllowed(context, email)) { | ||
| throw new AloreAuthError(ErrorTypes.EMAIL_DOMAIN_NOT_ALLOWED, 'Email domain not allowed', 400); | ||
| } | ||
| const { firebaseCompatible } = context.authProviderConfigs || {}; | ||
@@ -108,3 +80,3 @@ const response = yield this.fetchWithProgressiveBackoff(`/auth/v1/account-registration${firebaseCompatible ? `?firebaseCompatibleToken=${firebaseCompatible}` : ''}`, { | ||
| return data; | ||
| throw new Error(data.message || data.error || 'Authentication failed'); | ||
| yield this.throwParsedResponseError(response); | ||
| }), | ||
@@ -124,10 +96,7 @@ confirmPassword: (context, event) => __awaiter(this, void 0, void 0, function* () { | ||
| if (!response.ok) | ||
| return {}; | ||
| return { error: response === null || response === void 0 ? void 0 : response.statusText }; | ||
| yield this.throwParsedResponseError(response); | ||
| return {}; | ||
| }), | ||
| sendConfirmationEmail: (context, event) => __awaiter(this, void 0, void 0, function* () { | ||
| const { email, nickname, locale } = event.payload; | ||
| if (!this.services.isEmailAllowed(context, email)) { | ||
| throw new AloreAuthError(ErrorTypes.EMAIL_DOMAIN_NOT_ALLOWED, 'Email domain not allowed', 400); | ||
| } | ||
| const searchParams = new URLSearchParams(); | ||
@@ -156,13 +125,7 @@ const url = '/auth/v1/confirmation-email'; | ||
| } | ||
| if (response.status === 403) { | ||
| const resJson = yield response.json(); | ||
| throw new Error(resJson); | ||
| } | ||
| return { error: response === null || response === void 0 ? void 0 : response.statusText }; | ||
| // Throw parsed error for machine to consume | ||
| yield this.throwParsedResponseError(response); | ||
| }), | ||
| sendCode: (context, event) => __awaiter(this, void 0, void 0, function* () { | ||
| const { email } = event.payload; | ||
| if (!this.services.isEmailAllowed(context, email)) { | ||
| throw new AloreAuthError(ErrorTypes.EMAIL_DOMAIN_NOT_ALLOWED, 'Email domain not allowed', 400); | ||
| } | ||
| const response = yield this.fetchWithProgressiveBackoff(`/reset-password`, { | ||
@@ -178,3 +141,3 @@ method: 'POST', | ||
| if (!response.ok) | ||
| return { error: response === null || response === void 0 ? void 0 : response.statusText }; | ||
| yield this.throwParsedResponseError(response); | ||
| return {}; | ||
@@ -185,5 +148,2 @@ }), | ||
| const { email, passwordHash, device, locale } = event.payload; | ||
| if (!this.services.isEmailAllowed(context, email || context.credentialEmail)) { | ||
| throw new AloreAuthError(ErrorTypes.EMAIL_DOMAIN_NOT_ALLOWED, 'Email domain not allowed', 400); | ||
| } | ||
| const { credentialEmail } = context; | ||
@@ -217,3 +177,3 @@ const searchParams = new URLSearchParams(); | ||
| } | ||
| throw new Error((data === null || data === void 0 ? void 0 : data.message) || (data === null || data === void 0 ? void 0 : data.error) || data); | ||
| yield this.throwParsedResponseError(response); | ||
| } | ||
@@ -228,5 +188,2 @@ else { | ||
| const { email, nickname, device } = event.payload || context.registerUser; | ||
| if (email && !this.services.isEmailAllowed(context, email)) { | ||
| throw new AloreAuthError(ErrorTypes.EMAIL_DOMAIN_NOT_ALLOWED, 'Email domain not allowed', 400); | ||
| } | ||
| const startPasskeyRegistrationResponse = yield this.fetchWithProgressiveBackoff('/auth/v1/account-registration-passkey', { | ||
@@ -245,2 +202,4 @@ method: 'POST', | ||
| const data = yield startPasskeyRegistrationResponse.json(); | ||
| if (!startPasskeyRegistrationResponse.ok) | ||
| yield this.throwParsedResponseError(startPasskeyRegistrationResponse); | ||
| return data; | ||
@@ -251,5 +210,2 @@ }), | ||
| const { email, nickname, device, passkeyRegistration } = event.payload || {}; | ||
| if (email && !this.services.isEmailAllowed(context, email)) { | ||
| throw new AloreAuthError(ErrorTypes.EMAIL_DOMAIN_NOT_ALLOWED, 'Email domain not allowed', 400); | ||
| } | ||
| const response = yield this.fetchWithProgressiveBackoff('/auth/v1/account-registration-passkey-finish', { | ||
@@ -278,5 +234,2 @@ method: 'POST', | ||
| const email = (_c = event.payload) === null || _c === void 0 ? void 0 : _c.email; | ||
| if (email && !this.services.isEmailAllowed(context, email)) { | ||
| throw new AloreAuthError(ErrorTypes.EMAIL_DOMAIN_NOT_ALLOWED, 'Email domain not allowed', 400); | ||
| } | ||
| const searchParams = new URLSearchParams(); | ||
@@ -314,3 +267,3 @@ const url = '/auth/v1/login-passkey'; | ||
| return data; | ||
| throw new AloreAuthError(ErrorTypes.FAILED_TO_FETCH, data.message || data.error || data); | ||
| yield this.throwParsedResponseError(response); | ||
| }), | ||
@@ -335,3 +288,3 @@ // Hardware 2FA flow | ||
| return data; | ||
| throw new Error(data.message || data.error || 'Authentication failed'); | ||
| yield this.throwParsedResponseError(response); | ||
| }), | ||
@@ -374,3 +327,3 @@ authenticateWebauthn: (context, event) => __awaiter(this, void 0, void 0, function* () { | ||
| return data; | ||
| throw new Error(data.message || data.error || 'Authentication failed'); | ||
| yield this.throwParsedResponseError(response); | ||
| }), | ||
@@ -400,5 +353,2 @@ verifyDeviceCode: (context, event) => __awaiter(this, void 0, void 0, function* () { | ||
| const { credentialEmail, authProviderConfigs } = context; | ||
| if (!this.services.isEmailAllowed(context, email || credentialEmail)) { | ||
| throw new AloreAuthError(ErrorTypes.EMAIL_DOMAIN_NOT_ALLOWED, 'Email domain not allowed', 400); | ||
| } | ||
| const { firebaseCompatible } = authProviderConfigs || {}; | ||
@@ -435,3 +385,3 @@ const response = yield this.fetchWithProgressiveBackoff(`/auth/v1/email-2fa-verification${firebaseCompatible ? `?firebaseCompatibleToken=${firebaseCompatible}` : ''}`, { | ||
| if (!response.ok) | ||
| throw new Error((data === null || data === void 0 ? void 0 : data.message) || (data === null || data === void 0 ? void 0 : data.error) || data); | ||
| yield this.throwParsedResponseError(response); | ||
| return data; | ||
@@ -455,3 +405,3 @@ }), | ||
| return data; | ||
| throw new Error(data || 'Authentication failed'); | ||
| yield this.throwParsedResponseError(response); | ||
| }), | ||
@@ -461,5 +411,4 @@ fetchForgeData: (_, event) => __awaiter(this, void 0, void 0, function* () { | ||
| const data = (yield response.json()); | ||
| if (!response.ok) { | ||
| throw new Error(`Failed to fetchWithProgressiveBackoff: ${data}`); | ||
| } | ||
| if (!response.ok) | ||
| yield this.throwParsedResponseError(response); | ||
| return data; | ||
@@ -484,5 +433,2 @@ }), | ||
| if (response.ok) { | ||
| if (!this.services.isEmailAllowed(context, data.email)) { | ||
| throw new AloreAuthError(ErrorTypes.EMAIL_DOMAIN_NOT_ALLOWED, 'Email domain not allowed', 400); | ||
| } | ||
| return { | ||
@@ -500,5 +446,2 @@ googleOtpCode: data.otpCode, | ||
| if (response.status === 404) { | ||
| if (!this.services.isEmailAllowed(context, data.email)) { | ||
| throw new AloreAuthError(ErrorTypes.EMAIL_DOMAIN_NOT_ALLOWED, 'Email domain not allowed', 400); | ||
| } | ||
| return { | ||
@@ -514,3 +457,3 @@ isNewUser: true, | ||
| if (!response.ok) | ||
| throw new Error(data.error || data.message || data); | ||
| yield this.throwParsedResponseError(response); | ||
| return {}; | ||
@@ -620,2 +563,40 @@ }), | ||
| } | ||
| // eslint-disable-next-line class-methods-use-this | ||
| parseErrorResponse(response) { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| try { | ||
| const data = yield response.json(); | ||
| // Standardize to server payload when present | ||
| if (data && typeof data === 'object' && (data.message || data.status)) { | ||
| return { | ||
| status: data.status || response.status, | ||
| message: data.message || data.error || response.statusText, | ||
| timestamp: data.timestamp, | ||
| }; | ||
| } | ||
| return { status: response.status, message: response.statusText }; | ||
| } | ||
| catch (_a) { | ||
| return { status: response.status, message: response.statusText }; | ||
| } | ||
| }); | ||
| } | ||
| // eslint-disable-next-line class-methods-use-this | ||
| throwParsedResponseError(response) { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| const parsed = yield this.parseErrorResponse(response); | ||
| // Normalize well-known auth errors for consistent UI handling | ||
| let normalizedMessage = parsed.message || 'Request failed'; | ||
| if (parsed.status === 401) { | ||
| normalizedMessage = 'INVALID_CREDENTIALS'; | ||
| } | ||
| else if (parsed.status === 403 && parsed.message === 'EMAIL_NOT_ALLOWED') { | ||
| normalizedMessage = 'EMAIL_NOT_ALLOWED'; | ||
| } | ||
| const err = new AloreAuthError(ErrorTypes.FAILED_TO_FETCH, normalizedMessage); | ||
| // @ts-ignore attach server payload for consumers | ||
| err.data = Object.assign(Object.assign({}, parsed), { message: normalizedMessage }); | ||
| throw err; | ||
| }); | ||
| } | ||
| verifyBackendStatus() { | ||
@@ -622,0 +603,0 @@ return __awaiter(this, void 0, void 0, function* () { |
+1
-1
| { | ||
| "name": "@alore/auth-react-sdk", | ||
| "version": "1.1.0-alpha.6", | ||
| "version": "1.1.0-alpha.7", | ||
| "repository": "https://github.com/0xCarbon/alore-js", | ||
@@ -5,0 +5,0 @@ "description": "SDK for Alore Auth", |
74495
-3.68%1076
-3.32%