firebase-auth-cloudflare-workers
Version:
Zero-dependencies firebase auth library for Cloudflare Workers.
383 lines (382 loc) • 15.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.FirebaseAppError = exports.FirebaseAuthError = exports.PrefixedFirebaseError = exports.FirebaseError = exports.AuthClientErrorCode = exports.AppErrorCodes = exports.JwtErrorCode = exports.JwtError = void 0;
/**
* Jwt error code structure.
*
* @param code - The error code.
* @param message - The error message.
* @constructor
*/
class JwtError extends Error {
code;
message;
constructor(code, message) {
super(message);
this.code = code;
this.message = message;
this.__proto__ = JwtError.prototype;
}
}
exports.JwtError = JwtError;
/**
* JWT error codes.
*/
var JwtErrorCode;
(function (JwtErrorCode) {
JwtErrorCode["INVALID_ARGUMENT"] = "invalid-argument";
JwtErrorCode["INVALID_CREDENTIAL"] = "invalid-credential";
JwtErrorCode["TOKEN_EXPIRED"] = "token-expired";
JwtErrorCode["INVALID_SIGNATURE"] = "invalid-token";
JwtErrorCode["NO_MATCHING_KID"] = "no-matching-kid-error";
JwtErrorCode["NO_KID_IN_HEADER"] = "no-kid-error";
JwtErrorCode["KEY_FETCH_ERROR"] = "key-fetch-error";
})(JwtErrorCode || (exports.JwtErrorCode = JwtErrorCode = {}));
/**
* App client error codes and their default messages.
*/
class AppErrorCodes {
static INVALID_CREDENTIAL = 'invalid-credential';
static INTERNAL_ERROR = 'internal-error';
static NETWORK_ERROR = 'network-error';
static NETWORK_TIMEOUT = 'network-timeout';
static UNABLE_TO_PARSE_RESPONSE = 'unable-to-parse-response';
}
exports.AppErrorCodes = AppErrorCodes;
/**
* Auth client error codes and their default messages.
*/
class AuthClientErrorCode {
static INVALID_ARGUMENT = {
code: 'argument-error',
message: 'Invalid argument provided.',
};
static INVALID_CREDENTIAL = {
code: 'invalid-credential',
message: 'Invalid credential object provided.',
};
static ID_TOKEN_EXPIRED = {
code: 'id-token-expired',
message: 'The provided Firebase ID token is expired.',
};
static INVALID_ID_TOKEN = {
code: 'invalid-id-token',
message: 'The provided ID token is not a valid Firebase ID token.',
};
static ID_TOKEN_REVOKED = {
code: 'id-token-revoked',
message: 'The Firebase ID token has been revoked.',
};
static INTERNAL_ERROR = {
code: 'internal-error',
message: 'An internal error has occurred.',
};
static USER_NOT_FOUND = {
code: 'user-not-found',
message: 'There is no user record corresponding to the provided identifier.',
};
static USER_DISABLED = {
code: 'user-disabled',
message: 'The user record is disabled.',
};
static SESSION_COOKIE_EXPIRED = {
code: 'session-cookie-expired',
message: 'The Firebase session cookie is expired.',
};
static SESSION_COOKIE_REVOKED = {
code: 'session-cookie-revoked',
message: 'The Firebase session cookie has been revoked.',
};
static INVALID_SESSION_COOKIE_DURATION = {
code: 'invalid-session-cookie-duration',
message: 'The session cookie duration must be a valid number in milliseconds ' + 'between 5 minutes and 2 weeks.',
};
static INVALID_UID = {
code: 'invalid-uid',
message: 'The uid must be a non-empty string with at most 128 characters.',
};
static INVALID_TOKENS_VALID_AFTER_TIME = {
code: 'invalid-tokens-valid-after-time',
message: 'The tokensValidAfterTime must be a valid UTC number in seconds.',
};
static FORBIDDEN_CLAIM = {
code: 'reserved-claim',
message: 'The specified developer claim is reserved and cannot be specified.',
};
static INVALID_CLAIMS = {
code: 'invalid-claims',
message: 'The provided custom claim attributes are invalid.',
};
static CLAIMS_TOO_LARGE = {
code: 'claims-too-large',
message: 'Developer claims maximum payload size exceeded.',
};
}
exports.AuthClientErrorCode = AuthClientErrorCode;
/**
* Firebase error code structure. This extends Error.
*
* @param errorInfo - The error information (code and message).
* @constructor
*/
class FirebaseError extends Error {
errorInfo;
constructor(errorInfo) {
super(errorInfo.message);
this.errorInfo = errorInfo;
/* tslint:disable:max-line-length */
// Set the prototype explicitly. See the following link for more details:
// https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
/* tslint:enable:max-line-length */
this.__proto__ = FirebaseError.prototype;
}
/** @returns The error code. */
get code() {
return this.errorInfo.code;
}
/** @returns The error message. */
get message() {
return this.errorInfo.message;
}
/** @returns The object representation of the error. */
toJSON() {
return {
code: this.code,
message: this.message,
};
}
}
exports.FirebaseError = FirebaseError;
/**
* A FirebaseError with a prefix in front of the error code.
*
* @param codePrefix - The prefix to apply to the error code.
* @param code - The error code.
* @param message - The error message.
* @constructor
*/
class PrefixedFirebaseError extends FirebaseError {
codePrefix;
constructor(codePrefix, code, message) {
super({
code: `${codePrefix}/${code}`,
message,
});
this.codePrefix = codePrefix;
/* tslint:disable:max-line-length */
// Set the prototype explicitly. See the following link for more details:
// https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
/* tslint:enable:max-line-length */
this.__proto__ = PrefixedFirebaseError.prototype;
}
/**
* Allows the error type to be checked without needing to know implementation details
* of the code prefixing.
*
* @param code - The non-prefixed error code to test against.
* @returns True if the code matches, false otherwise.
*/
hasCode(code) {
return `${this.codePrefix}/${code}` === this.code;
}
}
exports.PrefixedFirebaseError = PrefixedFirebaseError;
/**
* Firebase Auth error code structure. This extends PrefixedFirebaseError.
*
* @param info - The error code info.
* @param [message] The error message. This will override the default
* message if provided.
* @constructor
*/
class FirebaseAuthError extends PrefixedFirebaseError {
constructor(info, message) {
// Override default message if custom message provided.
super('auth', info.code, message || info.message);
/* tslint:disable:max-line-length */
// Set the prototype explicitly. See the following link for more details:
// https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
/* tslint:enable:max-line-length */
this.__proto__ = FirebaseAuthError.prototype;
}
/**
* Creates the developer-facing error corresponding to the backend error code.
*
* @param serverErrorCode - The server error code.
* @param [message] The error message. The default message is used
* if not provided.
* @param [rawServerResponse] The error's raw server response.
* @returns The corresponding developer-facing error.
*/
static fromServerError(serverErrorCode, rawServerResponse) {
// serverErrorCode could contain additional details:
// ERROR_CODE : Detailed message which can also contain colons
const colonSeparator = (serverErrorCode || '').indexOf(':');
if (colonSeparator !== -1) {
serverErrorCode = serverErrorCode.substring(0, colonSeparator).trim();
}
// If not found, default to internal error.
const clientCodeKey = AUTH_SERVER_TO_CLIENT_CODE[serverErrorCode] || 'INTERNAL_ERROR';
const error = {
...AuthClientErrorCode.INTERNAL_ERROR,
...AuthClientErrorCode[clientCodeKey],
};
if (clientCodeKey === 'INTERNAL_ERROR' && typeof rawServerResponse !== 'undefined') {
try {
error.message += ` Raw server response: "${JSON.stringify(rawServerResponse)}"`;
}
catch (e) {
// Ignore JSON parsing error.
}
}
return new FirebaseAuthError(error);
}
}
exports.FirebaseAuthError = FirebaseAuthError;
/**
* Firebase App error code structure. This extends PrefixedFirebaseError.
*
* @param code - The error code.
* @param message - The error message.
* @constructor
*/
class FirebaseAppError extends PrefixedFirebaseError {
constructor(code, message) {
super('app', code, message);
/* tslint:disable:max-line-length */
// Set the prototype explicitly. See the following link for more details:
// https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
/* tslint:enable:max-line-length */
this.__proto__ = FirebaseAppError.prototype;
}
}
exports.FirebaseAppError = FirebaseAppError;
/** @const {ServerToClientCode} Auth server to client enum error codes. */
const AUTH_SERVER_TO_CLIENT_CODE = {
// Feature being configured or used requires a billing account.
BILLING_NOT_ENABLED: 'BILLING_NOT_ENABLED',
// Claims payload is too large.
CLAIMS_TOO_LARGE: 'CLAIMS_TOO_LARGE',
// Configuration being added already exists.
CONFIGURATION_EXISTS: 'CONFIGURATION_EXISTS',
// Configuration not found.
CONFIGURATION_NOT_FOUND: 'CONFIGURATION_NOT_FOUND',
// Provided credential has insufficient permissions.
INSUFFICIENT_PERMISSION: 'INSUFFICIENT_PERMISSION',
// Provided configuration has invalid fields.
INVALID_CONFIG: 'INVALID_CONFIG',
// Provided configuration identifier is invalid.
INVALID_CONFIG_ID: 'INVALID_PROVIDER_ID',
// ActionCodeSettings missing continue URL.
INVALID_CONTINUE_URI: 'INVALID_CONTINUE_URI',
// Dynamic link domain in provided ActionCodeSettings is not authorized.
INVALID_DYNAMIC_LINK_DOMAIN: 'INVALID_DYNAMIC_LINK_DOMAIN',
// uploadAccount provides an email that already exists.
DUPLICATE_EMAIL: 'EMAIL_ALREADY_EXISTS',
// uploadAccount provides a localId that already exists.
DUPLICATE_LOCAL_ID: 'UID_ALREADY_EXISTS',
// Request specified a multi-factor enrollment ID that already exists.
DUPLICATE_MFA_ENROLLMENT_ID: 'SECOND_FACTOR_UID_ALREADY_EXISTS',
// setAccountInfo email already exists.
EMAIL_EXISTS: 'EMAIL_ALREADY_EXISTS',
// /accounts:sendOobCode for password reset when user is not found.
EMAIL_NOT_FOUND: 'EMAIL_NOT_FOUND',
// Reserved claim name.
FORBIDDEN_CLAIM: 'FORBIDDEN_CLAIM',
// Invalid claims provided.
INVALID_CLAIMS: 'INVALID_CLAIMS',
// Invalid session cookie duration.
INVALID_DURATION: 'INVALID_SESSION_COOKIE_DURATION',
// Invalid email provided.
INVALID_EMAIL: 'INVALID_EMAIL',
// Invalid new email provided.
INVALID_NEW_EMAIL: 'INVALID_NEW_EMAIL',
// Invalid tenant display name. This can be thrown on CreateTenant and UpdateTenant.
INVALID_DISPLAY_NAME: 'INVALID_DISPLAY_NAME',
// Invalid ID token provided.
INVALID_ID_TOKEN: 'INVALID_ID_TOKEN',
// Invalid tenant/parent resource name.
INVALID_NAME: 'INVALID_NAME',
// OIDC configuration has an invalid OAuth client ID.
INVALID_OAUTH_CLIENT_ID: 'INVALID_OAUTH_CLIENT_ID',
// Invalid page token.
INVALID_PAGE_SELECTION: 'INVALID_PAGE_TOKEN',
// Invalid phone number.
INVALID_PHONE_NUMBER: 'INVALID_PHONE_NUMBER',
// Invalid agent project. Either agent project doesn't exist or didn't enable multi-tenancy.
INVALID_PROJECT_ID: 'INVALID_PROJECT_ID',
// Invalid provider ID.
INVALID_PROVIDER_ID: 'INVALID_PROVIDER_ID',
// Invalid service account.
INVALID_SERVICE_ACCOUNT: 'INVALID_SERVICE_ACCOUNT',
// Invalid testing phone number.
INVALID_TESTING_PHONE_NUMBER: 'INVALID_TESTING_PHONE_NUMBER',
// Invalid tenant type.
INVALID_TENANT_TYPE: 'INVALID_TENANT_TYPE',
// Missing Android package name.
MISSING_ANDROID_PACKAGE_NAME: 'MISSING_ANDROID_PACKAGE_NAME',
// Missing configuration.
MISSING_CONFIG: 'MISSING_CONFIG',
// Missing configuration identifier.
MISSING_CONFIG_ID: 'MISSING_PROVIDER_ID',
// Missing tenant display name: This can be thrown on CreateTenant and UpdateTenant.
MISSING_DISPLAY_NAME: 'MISSING_DISPLAY_NAME',
// Email is required for the specified action. For example a multi-factor user requires
// a verified email.
MISSING_EMAIL: 'MISSING_EMAIL',
// Missing iOS bundle ID.
MISSING_IOS_BUNDLE_ID: 'MISSING_IOS_BUNDLE_ID',
// Missing OIDC issuer.
MISSING_ISSUER: 'MISSING_ISSUER',
// No localId provided (deleteAccount missing localId).
MISSING_LOCAL_ID: 'MISSING_UID',
// OIDC configuration is missing an OAuth client ID.
MISSING_OAUTH_CLIENT_ID: 'MISSING_OAUTH_CLIENT_ID',
// Missing provider ID.
MISSING_PROVIDER_ID: 'MISSING_PROVIDER_ID',
// Missing SAML RP config.
MISSING_SAML_RELYING_PARTY_CONFIG: 'MISSING_SAML_RELYING_PARTY_CONFIG',
// Empty user list in uploadAccount.
MISSING_USER_ACCOUNT: 'MISSING_UID',
// Password auth disabled in console.
OPERATION_NOT_ALLOWED: 'OPERATION_NOT_ALLOWED',
// Provided credential has insufficient permissions.
PERMISSION_DENIED: 'INSUFFICIENT_PERMISSION',
// Phone number already exists.
PHONE_NUMBER_EXISTS: 'PHONE_NUMBER_ALREADY_EXISTS',
// Project not found.
PROJECT_NOT_FOUND: 'PROJECT_NOT_FOUND',
// In multi-tenancy context: project creation quota exceeded.
QUOTA_EXCEEDED: 'QUOTA_EXCEEDED',
// Currently only 5 second factors can be set on the same user.
SECOND_FACTOR_LIMIT_EXCEEDED: 'SECOND_FACTOR_LIMIT_EXCEEDED',
// Tenant not found.
TENANT_NOT_FOUND: 'TENANT_NOT_FOUND',
// Tenant ID mismatch.
TENANT_ID_MISMATCH: 'MISMATCHING_TENANT_ID',
// Token expired error.
TOKEN_EXPIRED: 'ID_TOKEN_EXPIRED',
// Continue URL provided in ActionCodeSettings has a domain that is not whitelisted.
UNAUTHORIZED_DOMAIN: 'UNAUTHORIZED_DOMAIN',
// A multi-factor user requires a supported first factor.
UNSUPPORTED_FIRST_FACTOR: 'UNSUPPORTED_FIRST_FACTOR',
// The request specified an unsupported type of second factor.
UNSUPPORTED_SECOND_FACTOR: 'UNSUPPORTED_SECOND_FACTOR',
// Operation is not supported in a multi-tenant context.
UNSUPPORTED_TENANT_OPERATION: 'UNSUPPORTED_TENANT_OPERATION',
// A verified email is required for the specified action. For example a multi-factor user
// requires a verified email.
UNVERIFIED_EMAIL: 'UNVERIFIED_EMAIL',
// User on which action is to be performed is not found.
USER_NOT_FOUND: 'USER_NOT_FOUND',
// User record is disabled.
USER_DISABLED: 'USER_DISABLED',
// Password provided is too weak.
WEAK_PASSWORD: 'INVALID_PASSWORD',
// Unrecognized reCAPTCHA action.
INVALID_RECAPTCHA_ACTION: 'INVALID_RECAPTCHA_ACTION',
// Unrecognized reCAPTCHA enforcement state.
INVALID_RECAPTCHA_ENFORCEMENT_STATE: 'INVALID_RECAPTCHA_ENFORCEMENT_STATE',
// reCAPTCHA is not enabled for account defender.
RECAPTCHA_NOT_ENABLED: 'RECAPTCHA_NOT_ENABLED',
};