auth0
Version:
Auth0 Node.js SDK for the Management API v2.
224 lines (223 loc) • 8.15 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CustomDomainHeader = CustomDomainHeader;
exports.withTimeout = withTimeout;
exports.withRetries = withRetries;
exports.withHeaders = withHeaders;
exports.withAbortSignal = withAbortSignal;
exports.withCustomDomainHeader = withCustomDomainHeader;
const index_js_1 = require("./core/index.js");
/**
* Helper functions to create common request options for the Auth0 Management API.
* These functions provide convenient ways to configure common request patterns.
*/
// Whitelisted path patterns for custom domain support
const WHITELISTED_PATTERNS = [
"^/api/v2/jobs/verification-email$",
"^/api/v2/tickets/email-verification$",
"^/api/v2/tickets/password-change$",
"^/api/v2/organizations/[^/]+/invitations$",
"^/api/v2/users$",
"^/api/v2/users/[^/]+$",
"^/api/v2/guardian/enrollments/ticket$",
];
// Function to compile the whitelisted patterns
function compileWhitelistedPathPatterns() {
return WHITELISTED_PATTERNS.map((pattern) => {
try {
return new RegExp(pattern);
}
catch (error) {
console.warn(`[CustomDomainWhitelist] Invalid regex pattern: ${pattern}`, error);
// Return a regex that never matches if pattern is invalid
return /(?!)/;
}
});
}
// Pre-compiled regex for matching whitelisted paths
const compiledWhitelistedPathRegexes = compileWhitelistedPathPatterns();
// Function to check if the path matches any whitelisted pattern
function isCustomDomainPathWhitelisted(path) {
if (!path || typeof path !== "string") {
return false;
}
return compiledWhitelistedPathRegexes.some((regex) => {
try {
return regex.test(path);
}
catch (error) {
console.warn(`[CustomDomainWhitelist] Error testing regex against path: ${path}`, error);
return false;
}
});
}
/**
* Helper functions that can be used directly in object literals for a more concise syntax.
* These functions return partial request options that can be spread into request options objects.
*/
/**
* Configure requests to use a custom domain header.
* Can be used directly in object literals with spread syntax.
* Note: This applies the header to all requests. For automatic path-based filtering,
* use withCustomDomainHeader in ManagementClient constructor options.
*
* @param domain - The custom domain to use (e.g., 'auth.example.com')
* @returns Partial request options with the custom domain header
*
* @example
* ```typescript
* const reqOptions = {
* ...CustomDomainHeader('auth.example.com'),
* timeoutInSeconds: 30
* };
* await client.actions.list({}, reqOptions);
* ```
*/
function CustomDomainHeader(domain) {
return {
headers: {
"Auth0-Custom-Domain": domain,
},
};
}
/**
* Configure requests with custom timeout settings.
* Can be used directly in object literals with spread syntax.
*
* @param seconds - Timeout in seconds
* @returns Partial request options with the specified timeout
*
* @example
* ```typescript
* const reqOptions = {
* ...withTimeout(30),
* maxRetries: 3
* };
* await client.actions.list({}, reqOptions);
* ```
*/
function withTimeout(seconds) {
return {
timeoutInSeconds: seconds,
};
}
/**
* Configure requests with custom retry settings.
* Can be used directly in object literals with spread syntax.
*
* @param retries - Number of retry attempts (0 to disable retries)
* @returns Partial request options with the specified retry count
*
* @example
* ```typescript
* const reqOptions = {
* ...withRetries(5),
* timeoutInSeconds: 30
* };
* await client.actions.list({}, reqOptions);
* ```
*/
function withRetries(retries) {
return {
maxRetries: retries,
};
}
/**
* Configure requests with custom headers.
* Can be used directly in object literals with spread syntax.
*
* @param headers - Object containing header key-value pairs
* @returns Partial request options with the specified headers
*
* @example
* ```typescript
* const reqOptions = {
* ...withHeaders({
* 'X-Request-ID': 'unique-id-123',
* 'X-Custom-Header': 'custom-value'
* }),
* timeoutInSeconds: 30
* };
* await client.actions.list({}, reqOptions);
* ```
*/
function withHeaders(headers) {
return {
headers,
};
}
/**
* Configure requests with an abort signal for cancellation.
* Can be used directly in object literals with spread syntax.
*
* @param signal - AbortSignal to control request cancellation
* @returns Partial request options with the specified abort signal
*
* @example
* ```typescript
* const controller = new AbortController();
* const reqOptions = {
* ...withAbortSignal(controller.signal),
* timeoutInSeconds: 30
* };
* const promise = client.actions.list({}, reqOptions);
* ```
*/
function withAbortSignal(signal) {
return {
abortSignal: signal,
};
}
/**
* INTERNAL: Configure a client with custom domain header that will be applied to whitelisted requests only.
* This creates a custom fetcher that intercepts requests and applies the whitelist logic.
*
* This function is for INTERNAL use only and is automatically used by ManagementClient
* when the withCustomDomainHeader option is provided in the constructor.
*
* Users should use the ergonomic API: `new ManagementClient({ ..., withCustomDomainHeader: 'domain' })`
*
* @internal
* @param domain - The custom domain to use (e.g., 'auth.example.com')
* @param options - The ManagementClient or resource client configuration options
* @returns Modified options with custom fetcher that implements whitelist logic and chains with existing fetcher if present
*/
function withCustomDomainHeader(domain, options) {
if (!domain || typeof domain !== "string" || domain.trim().length === 0) {
throw new Error("Domain parameter is required and must be a non-empty string");
}
const trimmedDomain = domain.trim();
// Preserve any existing custom fetcher from the options
const originalFetcher = options.fetcher || index_js_1.fetcher;
const customDomainFetcher = (args) => __awaiter(this, void 0, void 0, function* () {
if (!(args === null || args === void 0 ? void 0 : args.url)) {
throw new Error("Invalid fetcher arguments: URL is required");
}
// Parse URL and add custom domain header if path is whitelisted
try {
const url = new URL(args.url);
const path = url.pathname;
// Format path to ensure it starts with /api/v2/
const formattedPath = path.startsWith("/api/v2/") ? path : `/api/v2${path}`;
if (isCustomDomainPathWhitelisted(formattedPath)) {
// Modify args to include the custom domain header
args = Object.assign(Object.assign({}, args), { headers: Object.assign(Object.assign({}, args.headers), { "Auth0-Custom-Domain": trimmedDomain }) });
}
}
catch (error) {
throw new Error(`Invalid URL provided to custom domain header: ${args.url}`);
}
// Chain with the original fetcher (either user-provided or core fetcher)
return originalFetcher(args);
});
return Object.assign(Object.assign({}, options), { fetcher: customDomainFetcher });
}