{"version":3,"sources":["../src/auth-cognito.ts","../src/auth.ts","../src/cognito-signup-metadata.ts"],"sourcesContent":["import { Amplify } from 'aws-amplify'\nimport {\n  fetchAuthSession,\n  signInWithRedirect,\n  signOut,\n  getCurrentUser,\n  signIn as cognitoSignIn,\n  signUp as cognitoSignUp,\n  confirmSignUp as cognitoConfirmSignUp,\n  resendSignUpCode as cognitoResendSignUpCode,\n  resetPassword as cognitoResetPassword,\n  confirmResetPassword\n} from 'aws-amplify/auth'\nimport { registerAuthProvider, assertProviderConfig } from './auth'\nimport { splitSignupMetadata } from './cognito-signup-metadata'\nimport type { AuthClient, AuthProviderContext } from './types'\n\n/** Cognito auth provider factory — pass to createFoundation({ auth: cognitoAuth }) or import to auto-register */\nexport const cognitoAuth = async (config: Record<string, unknown>, _ctx: AuthProviderContext): Promise<AuthClient> => {\n  const cognito = assertProviderConfig(config, 'cognito', ['userPoolId', 'clientId', 'domain']) as\n    { userPoolId: string; clientId: string; region: string; domain: string; scope?: string }\n\n  Amplify.configure({\n    Auth: {\n      Cognito: {\n        userPoolId: cognito.userPoolId,\n        userPoolClientId: cognito.clientId,\n        loginWith: {\n          oauth: {\n            domain: cognito.domain.replace('https://', ''),\n            scopes: (cognito.scope || 'openid profile email').split(' '),\n            redirectSignIn: [window.location.origin],\n            redirectSignOut: [window.location.origin],\n            responseType: 'code'\n          }\n        }\n      }\n    }\n  })\n\n  return {\n    login: async () => { await signInWithRedirect() },\n    logout: async () => { await signOut() },\n    getUser: async () => {\n      try {\n        const user = await getCurrentUser()\n\n        // ID token claims are the authoritative profile source: signInDetails\n        // only exists for password sign-ins (absent after a hosted-UI redirect),\n        // and in email-alias pools `username` is the generated sub — an\n        // identifier, not a display name.\n        let claims: Record<string, unknown> = {}\n        try {\n          const session = await fetchAuthSession()\n          claims = (session.tokens?.idToken?.payload ?? {}) as Record<string, unknown>\n        } catch { /* no readable session — fall back to getCurrentUser fields */ }\n\n        const claimString = (key: string): string =>\n          typeof claims[key] === 'string' ? (claims[key] as string).trim() : ''\n\n        const email = claimString('email') || user.signInDetails?.loginId || ''\n        const fullName = [claimString('given_name'), claimString('family_name')]\n          .filter(Boolean)\n          .join(' ')\n        const usernameIsHandle = user.username !== '' && user.username !== user.userId\n        const name =\n          claimString('name') ||\n          fullName ||\n          (usernameIsHandle ? user.username : undefined)\n\n        return { id: user.userId, email, name }\n      } catch { return undefined }\n    },\n    getTokenSilently: async () => {\n      const session = await fetchAuthSession()\n      const token = session.tokens?.accessToken?.toString()\n      if (!token) throw new Error('No token available')\n      return token\n    },\n    isAuthenticated: async () => {\n      try {\n        await getCurrentUser()\n        return true\n      } catch { return false }\n    },\n\n    async handleCallback() {\n      // Amplify handles the callback automatically when configured with OAuth\n      // Just ensure the session is refreshed\n      await fetchAuthSession({ forceRefresh: true })\n    },\n\n    async signIn(email: string, password: string) {\n      const result = await cognitoSignIn({ username: email, password })\n      return {\n        isSignedIn: result.isSignedIn,\n        nextStep: result.nextStep as { signInStep: string; [key: string]: unknown } | undefined\n      }\n    },\n\n    async signUp(email: string, password: string, metadata?: Record<string, unknown>) {\n      const { userAttributes, clientMetadata } = splitSignupMetadata(metadata)\n      const result = await cognitoSignUp({\n        username: email,\n        password,\n        options: {\n          userAttributes: { email, ...userAttributes },\n          ...(Object.keys(clientMetadata).length ? { clientMetadata } : {})\n        }\n      })\n      return {\n        isSignUpComplete: result.isSignUpComplete,\n        userId: result.userId,\n        nextStep: result.nextStep as { signUpStep: string; [key: string]: unknown } | undefined\n      }\n    },\n\n    async confirmSignUp(email: string, code: string) {\n      await cognitoConfirmSignUp({ username: email, confirmationCode: code })\n    },\n\n    async resendSignUpCode(email: string) {\n      await cognitoResendSignUpCode({ username: email })\n    },\n\n    async forgotPassword(email: string) {\n      await cognitoResetPassword({ username: email })\n    },\n\n    async resetPassword(email: string, code: string, newPassword: string) {\n      await confirmResetPassword({ username: email, confirmationCode: code, newPassword })\n    }\n  }\n}\n\n// Auto-register when imported\nregisterAuthProvider('cognito', cognitoAuth)\n","/**\n * Auth core — provider registry and AuthService wrapper.\n * Provider implementations live in auth-auth0.ts and auth-cognito.ts.\n */\nimport type { AuthClient, AuthService, AuthProvider, AuthProviderContext, SignInResult, User } from './types'\n\nconst MAX_LISTENERS = 100\n\n/**\n * How long the password given to `signUp` stays in memory so `confirmSignUp` can\n * complete the sign-in itself. Long enough to cover reading a code out of an email,\n * short enough that an abandoned signup does not leave a password sitting in a tab\n * for the rest of the session.\n */\nconst PENDING_SIGN_UP_TTL_MS = 15 * 60 * 1000\n\n// --- Provider registry ---\n\nconst providers = new Map<string, AuthProvider>()\n\nexport function registerAuthProvider(name: string, factory: AuthProvider) {\n  providers.set(name, factory)\n}\n\n// Built-in \"none\" provider\nregisterAuthProvider('none', async () => ({\n  login: async () => {},\n  logout: async () => {},\n  getUser: async () => undefined,\n  getTokenSilently: async () => 'none',\n  isAuthenticated: async () => true\n}))\n\nexport interface AuthProviderConfig {\n  provider: string\n  [key: string]: unknown\n}\n\n/**\n * Validate the auth config block handed to a provider factory before it\n * touches the underlying auth library. The block comes from the backend's\n * public init response, not from local options — so a mismatch means the\n * backend isn't configured for this provider, and configuring the library\n * with empty values would only fail later with an unrelated-looking error.\n */\nexport function assertProviderConfig(\n  config: Record<string, unknown>,\n  provider: string,\n  requiredKeys: readonly string[]\n): Record<string, unknown> {\n  const reported = typeof config.provider === 'string' && config.provider ? config.provider : undefined\n  if (reported !== provider) {\n    throw new Error(\n      `[foundation-sdk] createFoundation was given the \"${provider}\" auth provider, but the backend ` +\n      `config endpoint reports provider \"${reported ?? 'none'}\". Auth factories are configured from ` +\n      `the init response, not local options. Set authenticationProvider: \"${provider}\" in the backend ` +\n      `config.json and redeploy (app:deploy) so /api/v1/public/init returns the ${provider} auth config.`\n    )\n  }\n  const block = config[provider]\n  const record = block && typeof block === 'object' ? block as Record<string, unknown> : undefined\n  const missing = requiredKeys.filter(key => {\n    const value = record?.[key]\n    return typeof value !== 'string' || value.trim() === ''\n  })\n  if (!record || missing.length > 0) {\n    throw new Error(\n      `[foundation-sdk] The backend reports provider \"${provider}\" but its config block is incomplete ` +\n      `(missing or empty: ${missing.join(', ')}). Check the ${provider} settings in the backend ` +\n      `config.json and redeploy (app:deploy) so /api/v1/public/init returns the full ${provider} config.`\n    )\n  }\n  return record\n}\n\nexport async function createAuthClient(config: AuthProviderConfig, ctx: AuthProviderContext): Promise<AuthClient> {\n  const factory = providers.get(config.provider)\n  if (!factory) {\n    throw new Error(\n      `Auth provider \"${config.provider}\" not registered. ` +\n      `Import \"foundation-sdk/${config.provider}\" to register it.`\n    )\n  }\n  return factory(config, ctx)\n}\n\n// --- AuthService wrapper ---\n\nexport interface AuthServiceOptions {\n  /** Sign in automatically after a successful `confirmSignUp`. Default true. */\n  autoSignInAfterConfirm?: boolean\n}\n\nexport function createAuthService(\n  client: AuthClient,\n  options: AuthServiceOptions = {}\n): AuthService & { _initUser(): Promise<void> } {\n  const autoSignInAfterConfirm = options.autoSignInAfterConfirm !== false\n  let user: User | null = null\n  const listeners: Array<(user: User | null) => void> = []\n\n  /**\n   * A confirmation code proves the user owns the address, but confirming does not\n   * create a session — so without this the caller has to bounce them to a login form\n   * to retype the password they entered a minute earlier. The credentials live in this\n   * closure only: never localStorage, never sessionStorage, never a cookie. They are\n   * dropped the moment they are used, superseded by another auth call, or stale.\n   */\n  let pendingSignUp: { email: string; password: string; expiresAt: number } | null = null\n  let pendingSignUpTimer: ReturnType<typeof setTimeout> | null = null\n\n  function clearPendingSignUp(): void {\n    pendingSignUp = null\n    if (pendingSignUpTimer !== null) {\n      clearTimeout(pendingSignUpTimer)\n      pendingSignUpTimer = null\n    }\n  }\n\n  function rememberPendingSignUp(email: string, password: string): void {\n    clearPendingSignUp()\n    if (!autoSignInAfterConfirm || !email || !password) return\n    pendingSignUp = { email, password, expiresAt: Date.now() + PENDING_SIGN_UP_TTL_MS }\n    pendingSignUpTimer = setTimeout(clearPendingSignUp, PENDING_SIGN_UP_TTL_MS)\n    // Background tabs throttle timers and Node would hold the process open for one,\n    // so `expiresAt` is the guard that actually decides; the timer only scrubs early.\n    const handle = pendingSignUpTimer as unknown as { unref?: () => void }\n    if (typeof handle.unref === 'function') handle.unref()\n  }\n\n  /** Returns the held credentials for `email` exactly once, then forgets them. */\n  function takePendingSignUp(email: string): { email: string; password: string } | null {\n    const pending = pendingSignUp\n    clearPendingSignUp()\n    if (!pending || pending.expiresAt <= Date.now()) return null\n    // Compare loosely (Cognito treats email aliases case-insensitively) but sign in with\n    // the username signUp actually used, which is the one the pool has a record for.\n    if (pending.email.trim().toLowerCase() !== email.trim().toLowerCase()) return null\n    return { email: pending.email, password: pending.password }\n  }\n\n  function notifyListeners() {\n    listeners.forEach(fn => { try { fn(user) } catch { /* */ } })\n  }\n\n  async function refreshUser() {\n    const authUser = await client.getUser()\n    user = authUser ? { id: authUser.id, email: authUser.email, name: authUser.name, picture: authUser.picture } : null\n  }\n\n  return {\n    get user() { return user },\n    get isAuthenticated() { return !!user },\n\n    async getToken() {\n      return client.getTokenSilently()\n    },\n\n    async login(options) {\n      await client.login(options)\n      await refreshUser()\n      notifyListeners()\n    },\n\n    async logout(options) {\n      clearPendingSignUp()\n      await client.logout(options)\n      user = null\n      notifyListeners()\n    },\n\n    async handleCallback(url?) {\n      if (!client.handleCallback) throw new Error('handleCallback not supported by this auth provider')\n      await client.handleCallback(url)\n      await refreshUser()\n      notifyListeners()\n    },\n\n    async signIn(email, password) {\n      if (!client.signIn) throw new Error('signIn not supported by this auth provider')\n      // An explicit sign-in supersedes whatever signUp left behind, success or not.\n      clearPendingSignUp()\n      const result = await client.signIn(email, password)\n      // Only refresh user state if the sign-in actually completed.\n      // If a provider returns isSignedIn: false with a next step (e.g. CONFIRM_SIGN_UP),\n      // the user isn't really signed in and we shouldn't populate the user ref.\n      if (result.isSignedIn) {\n        await refreshUser()\n        notifyListeners()\n      }\n      return result\n    },\n\n    async signUp(email, password, metadata) {\n      if (!client.signUp) throw new Error('signUp not supported by this auth provider')\n      const result = await client.signUp(email, password, metadata)\n      rememberPendingSignUp(email, password)\n      return result\n    },\n\n    async confirmSignUp(email, code) {\n      if (!client.confirmSignUp) throw new Error('confirmSignUp not supported by this auth provider')\n      await client.confirmSignUp(email, code)\n\n      const pending = takePendingSignUp(email)\n      if (!pending || !client.signIn) return { isSignedIn: false }\n\n      let result: SignInResult\n      try {\n        result = await client.signIn(pending.email, pending.password)\n      } catch {\n        // The account is confirmed — that is what this call promised, and turning a\n        // failed convenience sign-in into a thrown confirmation would make the caller\n        // replay a code that is already spent. Report no session and let them show\n        // the sign-in form.\n        return { isSignedIn: false }\n      }\n      if (result.isSignedIn) {\n        await refreshUser()\n        notifyListeners()\n      }\n      return result\n    },\n\n    async resendSignUpCode(email) {\n      if (!client.resendSignUpCode) throw new Error('resendSignUpCode not supported by this auth provider')\n      await client.resendSignUpCode(email)\n    },\n\n    async forgotPassword(email) {\n      if (!client.forgotPassword) throw new Error('forgotPassword not supported by this auth provider')\n      await client.forgotPassword(email)\n    },\n\n    async resetPassword(email, code, newPassword) {\n      if (!client.resetPassword) throw new Error('resetPassword not supported by this auth provider')\n      // Whatever signUp handed us is stale the moment the password changes.\n      clearPendingSignUp()\n      await client.resetPassword(email, code, newPassword)\n    },\n\n    onChange(callback) {\n      if (listeners.length >= MAX_LISTENERS) {\n        console.warn('[Foundation SDK] Auth listener limit reached.')\n        return () => {}\n      }\n      listeners.push(callback)\n      return () => {\n        const idx = listeners.indexOf(callback)\n        if (idx > -1) listeners.splice(idx, 1)\n      }\n    },\n\n    async _initUser() {\n      const authenticated = await client.isAuthenticated()\n      if (authenticated) await refreshUser()\n    }\n  }\n}\n","/**\n * Routes signUp metadata to the correct Cognito destination.\n *\n * Cognito's app client only permits writing a fixed set of user attributes\n * (email, given_name, family_name, ...). Sending any other key in\n * `userAttributes` fails with \"A client attempted to write unauthorized\n * attribute\". Profile fields live on the Foundation account, not the Cognito\n * user, so we forward them via `ClientMetadata` — which bypasses the writable-\n * attribute ACL, is never stored on the Cognito user, and reaches the backend\n * PreSignUp trigger, which persists them to the account.\n *\n * PAIRED WITH the backend allow-list in\n * core/source/modules/accounts/helpers/auth/signupProfileFields.ts — keep the\n * two field lists in sync. The backend ignores any ClientMetadata key not on\n * its allow-list, so an extra key here is dropped rather than persisted.\n */\nexport const SIGNUP_PROFILE_FIELDS = [\n  'name',\n  'nickname',\n  'picture',\n  'locale',\n  'timezone'\n] as const\n\nconst PROFILE_FIELD_SET = new Set<string>(SIGNUP_PROFILE_FIELDS)\n\n/**\n * Partition signUp metadata:\n * - allow-listed profile fields -> `clientMetadata` (persisted to the account)\n * - everything else (e.g. given_name, family_name) -> `userAttributes`\n *\n * Null/undefined values are dropped; all values are coerced to strings, since\n * both Cognito maps require string values.\n */\nexport function splitSignupMetadata(metadata: Record<string, unknown> = {}): {\n  userAttributes: Record<string, string>\n  clientMetadata: Record<string, string>\n} {\n  const userAttributes: Record<string, string> = {}\n  const clientMetadata: Record<string, string> = {}\n\n  for (const [key, value] of Object.entries(metadata)) {\n    if (value === null || value === undefined) continue\n    const stringValue = String(value)\n    if (PROFILE_FIELD_SET.has(key)) {\n      clientMetadata[key] = stringValue\n    } else {\n      userAttributes[key] = stringValue\n    }\n  }\n\n  return { userAttributes, clientMetadata }\n}\n"],"mappings":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,iBAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAwB,uBACxBC,EAWO,4BCMP,IAAMC,EAAY,IAAI,IAEf,SAASC,EAAqBC,EAAcC,EAAuB,CACxEH,EAAU,IAAIE,EAAMC,CAAO,CAC7B,CAGAF,EAAqB,OAAQ,UAAa,CACxC,MAAO,SAAY,CAAC,EACpB,OAAQ,SAAY,CAAC,EACrB,QAAS,SAAS,GAClB,iBAAkB,SAAY,OAC9B,gBAAiB,SAAY,EAC/B,EAAE,EAcK,SAASG,EACdC,EACAC,EACAC,EACyB,CACzB,IAAMC,EAAW,OAAOH,EAAO,UAAa,UAAYA,EAAO,SAAWA,EAAO,SAAW,OAC5F,GAAIG,IAAaF,EACf,MAAM,IAAI,MACR,oDAAoDA,CAAQ,sEACvBE,GAAY,MAAM,4GACeF,CAAQ,6FACFA,CAAQ,eACtF,EAEF,IAAMG,EAAQJ,EAAOC,CAAQ,EACvBI,EAASD,GAAS,OAAOA,GAAU,SAAWA,EAAmC,OACjFE,EAAUJ,EAAa,OAAOK,GAAO,CACzC,IAAMC,EAAQH,IAASE,CAAG,EAC1B,OAAO,OAAOC,GAAU,UAAYA,EAAM,KAAK,IAAM,EACvD,CAAC,EACD,GAAI,CAACH,GAAUC,EAAQ,OAAS,EAC9B,MAAM,IAAI,MACR,kDAAkDL,CAAQ,2DACpCK,EAAQ,KAAK,IAAI,CAAC,gBAAgBL,CAAQ,0GACiBA,CAAQ,UAC3F,EAEF,OAAOI,CACT,CCzDO,IAAMI,EAAwB,CACnC,OACA,WACA,UACA,SACA,UACF,EAEMC,EAAoB,IAAI,IAAYD,CAAqB,EAUxD,SAASE,EAAoBC,EAAoC,CAAC,EAGvE,CACA,IAAMC,EAAyC,CAAC,EAC1CC,EAAyC,CAAC,EAEhD,OAAW,CAACC,EAAKC,CAAK,IAAK,OAAO,QAAQJ,CAAQ,EAAG,CACnD,GAAII,GAAU,KAA6B,SAC3C,IAAMC,EAAc,OAAOD,CAAK,EAC5BN,EAAkB,IAAIK,CAAG,EAC3BD,EAAeC,CAAG,EAAIE,EAEtBJ,EAAeE,CAAG,EAAIE,CAE1B,CAEA,MAAO,CAAE,eAAAJ,EAAgB,eAAAC,CAAe,CAC1C,CFlCO,IAAMI,EAAc,MAAOC,EAAiCC,IAAmD,CACpH,IAAMC,EAAUC,EAAqBH,EAAQ,UAAW,CAAC,aAAc,WAAY,QAAQ,CAAC,EAG5F,iBAAQ,UAAU,CAChB,KAAM,CACJ,QAAS,CACP,WAAYE,EAAQ,WACpB,iBAAkBA,EAAQ,SAC1B,UAAW,CACT,MAAO,CACL,OAAQA,EAAQ,OAAO,QAAQ,WAAY,EAAE,EAC7C,QAASA,EAAQ,OAAS,wBAAwB,MAAM,GAAG,EAC3D,eAAgB,CAAC,OAAO,SAAS,MAAM,EACvC,gBAAiB,CAAC,OAAO,SAAS,MAAM,EACxC,aAAc,MAChB,CACF,CACF,CACF,CACF,CAAC,EAEM,CACL,MAAO,SAAY,CAAE,QAAM,sBAAmB,CAAE,EAChD,OAAQ,SAAY,CAAE,QAAM,WAAQ,CAAE,EACtC,QAAS,SAAY,CACnB,GAAI,CACF,IAAME,EAAO,QAAM,kBAAe,EAM9BC,EAAkC,CAAC,EACvC,GAAI,CAEFA,GADgB,QAAM,oBAAiB,GACrB,QAAQ,SAAS,SAAW,CAAC,CACjD,MAAQ,CAAiE,CAEzE,IAAMC,EAAeC,GACnB,OAAOF,EAAOE,CAAG,GAAM,SAAYF,EAAOE,CAAG,EAAa,KAAK,EAAI,GAE/DC,EAAQF,EAAY,OAAO,GAAKF,EAAK,eAAe,SAAW,GAC/DK,EAAW,CAACH,EAAY,YAAY,EAAGA,EAAY,aAAa,CAAC,EACpE,OAAO,OAAO,EACd,KAAK,GAAG,EACLI,EAAmBN,EAAK,WAAa,IAAMA,EAAK,WAAaA,EAAK,OAClEO,EACJL,EAAY,MAAM,GAClBG,IACCC,EAAmBN,EAAK,SAAW,QAEtC,MAAO,CAAE,GAAIA,EAAK,OAAQ,MAAAI,EAAO,KAAAG,CAAK,CACxC,MAAQ,CAAE,MAAiB,CAC7B,EACA,iBAAkB,SAAY,CAE5B,IAAMC,GADU,QAAM,oBAAiB,GACjB,QAAQ,aAAa,SAAS,EACpD,GAAI,CAACA,EAAO,MAAM,IAAI,MAAM,oBAAoB,EAChD,OAAOA,CACT,EACA,gBAAiB,SAAY,CAC3B,GAAI,CACF,eAAM,kBAAe,EACd,EACT,MAAQ,CAAE,MAAO,EAAM,CACzB,EAEA,MAAM,gBAAiB,CAGrB,QAAM,oBAAiB,CAAE,aAAc,EAAK,CAAC,CAC/C,EAEA,MAAM,OAAOJ,EAAeK,EAAkB,CAC5C,IAAMC,EAAS,QAAM,EAAAC,QAAc,CAAE,SAAUP,EAAO,SAAAK,CAAS,CAAC,EAChE,MAAO,CACL,WAAYC,EAAO,WACnB,SAAUA,EAAO,QACnB,CACF,EAEA,MAAM,OAAON,EAAeK,EAAkBG,EAAoC,CAChF,GAAM,CAAE,eAAAC,EAAgB,eAAAC,CAAe,EAAIC,EAAoBH,CAAQ,EACjEF,EAAS,QAAM,EAAAM,QAAc,CACjC,SAAUZ,EACV,SAAAK,EACA,QAAS,CACP,eAAgB,CAAE,MAAAL,EAAO,GAAGS,CAAe,EAC3C,GAAI,OAAO,KAAKC,CAAc,EAAE,OAAS,CAAE,eAAAA,CAAe,EAAI,CAAC,CACjE,CACF,CAAC,EACD,MAAO,CACL,iBAAkBJ,EAAO,iBACzB,OAAQA,EAAO,OACf,SAAUA,EAAO,QACnB,CACF,EAEA,MAAM,cAAcN,EAAea,EAAc,CAC/C,QAAM,EAAAC,eAAqB,CAAE,SAAUd,EAAO,iBAAkBa,CAAK,CAAC,CACxE,EAEA,MAAM,iBAAiBb,EAAe,CACpC,QAAM,EAAAe,kBAAwB,CAAE,SAAUf,CAAM,CAAC,CACnD,EAEA,MAAM,eAAeA,EAAe,CAClC,QAAM,EAAAgB,eAAqB,CAAE,SAAUhB,CAAM,CAAC,CAChD,EAEA,MAAM,cAAcA,EAAea,EAAcI,EAAqB,CACpE,QAAM,wBAAqB,CAAE,SAAUjB,EAAO,iBAAkBa,EAAM,YAAAI,CAAY,CAAC,CACrF,CACF,CACF,EAGAC,EAAqB,UAAW3B,CAAW","names":["auth_cognito_exports","__export","cognitoAuth","__toCommonJS","import_aws_amplify","import_auth","providers","registerAuthProvider","name","factory","assertProviderConfig","config","provider","requiredKeys","reported","block","record","missing","key","value","SIGNUP_PROFILE_FIELDS","PROFILE_FIELD_SET","splitSignupMetadata","metadata","userAttributes","clientMetadata","key","value","stringValue","cognitoAuth","config","_ctx","cognito","assertProviderConfig","user","claims","claimString","key","email","fullName","usernameIsHandle","name","token","password","result","cognitoSignIn","metadata","userAttributes","clientMetadata","splitSignupMetadata","cognitoSignUp","code","cognitoConfirmSignUp","cognitoResendSignUpCode","cognitoResetPassword","newPassword","registerAuthProvider"]}