UNPKG

firebase-functions

Version:
235 lines (233 loc) 8.19 kB
import { __export } from "../../_virtual/rolldown_runtime.mjs"; import { RESET_VALUE } from "../../common/options.mjs"; import { initV2Endpoint } from "../../runtime/manifest.mjs"; import { withInit } from "../../common/onInit.mjs"; import { HttpsError } from "../../common/providers/https.mjs"; import { userRecordConstructor, wrapHandler } from "../../common/providers/identity.mjs"; import { wrapTraceContext } from "../trace.mjs"; import { getGlobalOptions, optionsToEndpoint } from "../options.mjs"; //#region src/v2/providers/identity.ts var identity_exports = /* @__PURE__ */ __export({ HttpsError: () => HttpsError, IS_NOT_TENANT: () => IS_NOT_TENANT, beforeEmailSent: () => beforeEmailSent, beforeOperation: () => beforeOperation, beforeSmsSent: () => beforeSmsSent, beforeUserCreated: () => beforeUserCreated, beforeUserSignedIn: () => beforeUserSignedIn, getOpts: () => getOpts, onUserCreated: () => onUserCreated, onUserDeleted: () => onUserDeleted }); /** * Handles an event that is triggered before a user is created. * @param optsOrHandler - Either an object containing function options, or an event handler (run before user creation). * @param handler? - If defined, an event handler which is run every time before a user is created. */ function beforeUserCreated(optsOrHandler, handler) { return beforeOperation("beforeCreate", optsOrHandler, handler); } /** * Handles an event that is triggered before a user is signed in. * @param optsOrHandler - Either an object containing function options, or an event handler (run before user signin). * @param handler - Event handler which is run every time before a user is signed in. */ function beforeUserSignedIn(optsOrHandler, handler) { return beforeOperation("beforeSignIn", optsOrHandler, handler); } /** * Handles an event that is triggered before an email is sent to a user. * @param optsOrHandler- Either an object containing function options, or an event handler that is run before an email is sent to a user. * @param handler - Event handler that is run before an email is sent to a user. */ function beforeEmailSent(optsOrHandler, handler) { return beforeOperation("beforeSendEmail", optsOrHandler, handler); } /** * Handles an event that is triggered before an SMS is sent to a user. * @param optsOrHandler - Either an object containing function options, or an event handler that is run before an SMS is sent to a user. * @param handler - Event handler that is run before an SMS is sent to a user. */ function beforeSmsSent(optsOrHandler, handler) { return beforeOperation("beforeSendSms", optsOrHandler, handler); } /** @hidden */ function beforeOperation(eventType, optsOrHandler, handler) { if (!handler || typeof optsOrHandler === "function") { handler = optsOrHandler; optsOrHandler = {}; } const { opts,...blockingOptions } = getOpts(optsOrHandler); const annotatedHandler = Object.assign(handler, { platform: "gcfv2" }); const func = wrapTraceContext(withInit(wrapHandler(eventType, annotatedHandler))); const legacyEventType = `providers/cloud.auth/eventTypes/user.${eventType}`; /** Endpoint */ const baseOptsEndpoint = optionsToEndpoint(getGlobalOptions()); const specificOptsEndpoint = optionsToEndpoint(opts, "identity"); func.__endpoint = { ...initV2Endpoint(getGlobalOptions(), opts), platform: "gcfv2", ...baseOptsEndpoint, ...specificOptsEndpoint, labels: { ...baseOptsEndpoint?.labels, ...specificOptsEndpoint?.labels }, blockingTrigger: { eventType: legacyEventType, options: { ...(eventType === "beforeCreate" || eventType === "beforeSignIn") && blockingOptions } } }; func.__requiredAPIs = [{ api: "identitytoolkit.googleapis.com", reason: "Needed for auth blocking functions" }]; func.run = handler; return func; } /** @hidden */ function getOpts(blockingOptions) { const accessToken = blockingOptions.accessToken || false; const idToken = blockingOptions.idToken || false; const refreshToken = blockingOptions.refreshToken || false; const opts = { ...blockingOptions }; delete opts.accessToken; delete opts.idToken; delete opts.refreshToken; return { opts, accessToken, idToken, refreshToken }; } /** * constant to represent the absence of tenant ID. * @internal */ const IS_NOT_TENANT = RESET_VALUE; function getOptsAndHandler(optsOrHandler, handler) { if (typeof optsOrHandler === "function") { return { opts: {}, handler: optsOrHandler }; } return { opts: optsOrHandler, handler }; } const PROJECT_ID_REGEX = /(?:^|\/)projects\/([^\/]+)/; /** * Converts the v2 Eventarc (`AuthEventData`) protobuf wire protocol (`value`/`oldValue`, `createTime`, `photoUrl`) * into the v1 `LegacyEvent` wire protocol expected by `userRecordConstructor`. * @hidden */ function convertV2EventToV1Event(rawData) { if (!rawData || typeof rawData !== "object") { return undefined; } const dataObj = rawData; let rawUser; if ("value" in dataObj) { rawUser = dataObj.value; } else if ("oldValue" in dataObj) { rawUser = dataObj.oldValue; } else if ("old_value" in dataObj) { rawUser = dataObj.old_value; } else { rawUser = dataObj; } if (!rawUser || typeof rawUser !== "object") { return undefined; } const userData = { ...rawUser }; if (userData.photoUrl && !userData.photoURL) { userData.photoURL = userData.photoUrl; } if (userData.metadata && typeof userData.metadata === "object") { const meta = { ...userData.metadata }; if (meta.createTime && !meta.createdAt && !meta.creationTime) { meta.creationTime = meta.createTime; } userData.metadata = meta; } return userRecordConstructor(userData); } /** * Normalizes raw CloudEvents from Eventarc into AuthEvent<User>. * Eventarc wraps v2 Authentication user payloads inside an `AuthEventData` * protobuf envelope (`value` for creation events, `oldValue` for deletion events). * We unbox the envelope (falling back to `raw.data` for unit tests) and normalize * protobuf-specific field names (`createTime` -> `creationTime`, `photoUrl` -> `photoURL`). * @hidden */ function getAuthEvent(raw) { const event = { ...raw }; if (raw.data !== undefined && raw.data !== null) { event.data = convertV2EventToV1Event(raw.data); } const rawAny = raw; const tenantId = rawAny.tenantid || rawAny.tenantId; if (tenantId) { event.tenantId = tenantId; } if (raw.source) { const match = raw.source.match(PROJECT_ID_REGEX); if (match) { event.project = match[1]; } } return event; } /** @hidden */ function makeAuthTrigger(eventType, optsOrHandler, handler) { const { opts, handler: handlerFunc } = getOptsAndHandler(optsOrHandler, handler); if (typeof handlerFunc !== "function") { throw new Error("The handler must be a function."); } const wrappedHandler = wrapTraceContext(withInit(handlerFunc)); const func = ((raw) => { const event = getAuthEvent(raw); return wrappedHandler(event); }); func.run = handlerFunc; const baseOptsEndpoint = optionsToEndpoint(getGlobalOptions()); const specificOptsEndpoint = optionsToEndpoint(opts); const endpoint = { ...initV2Endpoint(getGlobalOptions(), opts), platform: "gcfv2", ...baseOptsEndpoint, ...specificOptsEndpoint, labels: { ...baseOptsEndpoint?.labels, ...specificOptsEndpoint?.labels }, eventTrigger: { eventType, eventFilters: {}, retry: opts.retry ?? false, region: "global" } }; if (opts.tenantId !== undefined) { if (opts.tenantId === IS_NOT_TENANT) { endpoint.eventTrigger.eventFilters["tenantid"] = ""; } else { endpoint.eventTrigger.eventFilters["tenantid"] = opts.tenantId; } } func.__endpoint = endpoint; return func; } const USER_CREATED_EVENT = "google.firebase.auth.user.v2.created"; function onUserCreated(optsOrHandler, handler) { return makeAuthTrigger(USER_CREATED_EVENT, optsOrHandler, handler); } const USER_DELETED_EVENT = "google.firebase.auth.user.v2.deleted"; function onUserDeleted(optsOrHandler, handler) { return makeAuthTrigger(USER_DELETED_EVENT, optsOrHandler, handler); } //#endregion export { HttpsError, IS_NOT_TENANT, beforeEmailSent, beforeOperation, beforeSmsSent, beforeUserCreated, beforeUserSignedIn, getOpts, identity_exports, onUserCreated, onUserDeleted };