better-auth
Version:
The most comprehensive authentication framework for TypeScript.
1 lines • 39.6 kB
Source Map (JSON)
{"version":3,"file":"account.mjs","names":["e: any","account: Account | undefined","newTokens: OAuth2Tokens | null","refreshToken","updatedAccount: Record<string, any> | null","refreshToken: string | null | undefined","tokens: OAuth2Tokens"],"sources":["../../../src/api/routes/account.ts"],"sourcesContent":["import { createAuthEndpoint } from \"@better-auth/core/api\";\nimport type { Account } from \"@better-auth/core/db\";\nimport { BASE_ERROR_CODES } from \"@better-auth/core/error\";\nimport type { OAuth2Tokens } from \"@better-auth/core/oauth2\";\nimport { SocialProviderListEnum } from \"@better-auth/core/social-providers\";\nimport { APIError } from \"better-call\";\nimport * as z from \"zod\";\nimport {\n\tgetAccountCookie,\n\tsetAccountCookie,\n} from \"../../cookies/session-store\";\nimport { generateState } from \"../../oauth2/state\";\nimport { decryptOAuthToken, setTokenUtil } from \"../../oauth2/utils\";\nimport {\n\tfreshSessionMiddleware,\n\tgetSessionFromCtx,\n\tsessionMiddleware,\n} from \"./session\";\n\nexport const listUserAccounts = createAuthEndpoint(\n\t\"/list-accounts\",\n\t{\n\t\tmethod: \"GET\",\n\t\tuse: [sessionMiddleware],\n\t\tmetadata: {\n\t\t\topenapi: {\n\t\t\t\toperationId: \"listUserAccounts\",\n\t\t\t\tdescription: \"List all accounts linked to the user\",\n\t\t\t\tresponses: {\n\t\t\t\t\t\"200\": {\n\t\t\t\t\t\tdescription: \"Success\",\n\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\ttype: \"array\",\n\t\t\t\t\t\t\t\t\titems: {\n\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tid: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\tproviderId: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\tcreatedAt: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\tformat: \"date-time\",\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\tupdatedAt: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\tformat: \"date-time\",\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\taccountId: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\tuserId: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\tscopes: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: \"array\",\n\t\t\t\t\t\t\t\t\t\t\t\titems: {\n\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\trequired: [\n\t\t\t\t\t\t\t\t\t\t\t\"id\",\n\t\t\t\t\t\t\t\t\t\t\t\"providerId\",\n\t\t\t\t\t\t\t\t\t\t\t\"createdAt\",\n\t\t\t\t\t\t\t\t\t\t\t\"updatedAt\",\n\t\t\t\t\t\t\t\t\t\t\t\"accountId\",\n\t\t\t\t\t\t\t\t\t\t\t\"userId\",\n\t\t\t\t\t\t\t\t\t\t\t\"scopes\",\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t},\n\tasync (c) => {\n\t\tconst session = c.context.session;\n\t\tconst accounts = await c.context.internalAdapter.findAccounts(\n\t\t\tsession.user.id,\n\t\t);\n\t\treturn c.json(\n\t\t\taccounts.map((a) => ({\n\t\t\t\tid: a.id,\n\t\t\t\tproviderId: a.providerId,\n\t\t\t\tcreatedAt: a.createdAt,\n\t\t\t\tupdatedAt: a.updatedAt,\n\t\t\t\taccountId: a.accountId,\n\t\t\t\tuserId: a.userId,\n\t\t\t\tscopes: a.scope?.split(\",\") || [],\n\t\t\t})),\n\t\t);\n\t},\n);\n\nexport const linkSocialAccount = createAuthEndpoint(\n\t\"/link-social\",\n\t{\n\t\tmethod: \"POST\",\n\t\trequireHeaders: true,\n\t\tbody: z.object({\n\t\t\t/**\n\t\t\t * Callback URL to redirect to after the user has signed in.\n\t\t\t */\n\t\t\tcallbackURL: z\n\t\t\t\t.string()\n\t\t\t\t.meta({\n\t\t\t\t\tdescription: \"The URL to redirect to after the user has signed in\",\n\t\t\t\t})\n\t\t\t\t.optional(),\n\t\t\t/**\n\t\t\t * OAuth2 provider to use\n\t\t\t */\n\t\t\tprovider: SocialProviderListEnum,\n\t\t\t/**\n\t\t\t * ID Token for direct authentication without redirect\n\t\t\t */\n\t\t\tidToken: z\n\t\t\t\t.object({\n\t\t\t\t\ttoken: z.string(),\n\t\t\t\t\tnonce: z.string().optional(),\n\t\t\t\t\taccessToken: z.string().optional(),\n\t\t\t\t\trefreshToken: z.string().optional(),\n\t\t\t\t\tscopes: z.array(z.string()).optional(),\n\t\t\t\t})\n\t\t\t\t.optional(),\n\t\t\t/**\n\t\t\t * Whether to allow sign up for new users\n\t\t\t */\n\t\t\trequestSignUp: z.boolean().optional(),\n\t\t\t/**\n\t\t\t * Additional scopes to request when linking the account.\n\t\t\t * This is useful for requesting additional permissions when\n\t\t\t * linking a social account compared to the initial authentication.\n\t\t\t */\n\t\t\tscopes: z\n\t\t\t\t.array(z.string())\n\t\t\t\t.meta({\n\t\t\t\t\tdescription: \"Additional scopes to request from the provider\",\n\t\t\t\t})\n\t\t\t\t.optional(),\n\t\t\t/**\n\t\t\t * The URL to redirect to if there is an error during the link process.\n\t\t\t */\n\t\t\terrorCallbackURL: z\n\t\t\t\t.string()\n\t\t\t\t.meta({\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"The URL to redirect to if there is an error during the link process\",\n\t\t\t\t})\n\t\t\t\t.optional(),\n\t\t\t/**\n\t\t\t * Disable automatic redirection to the provider\n\t\t\t *\n\t\t\t * This is useful if you want to handle the redirection\n\t\t\t * yourself like in a popup or a different tab.\n\t\t\t */\n\t\t\tdisableRedirect: z\n\t\t\t\t.boolean()\n\t\t\t\t.meta({\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Disable automatic redirection to the provider. Useful for handling the redirection yourself\",\n\t\t\t\t})\n\t\t\t\t.optional(),\n\t\t\t/**\n\t\t\t * Any additional data to pass through the oauth flow.\n\t\t\t */\n\t\t\tadditionalData: z.record(z.string(), z.any()).optional(),\n\t\t}),\n\t\tuse: [sessionMiddleware],\n\t\tmetadata: {\n\t\t\topenapi: {\n\t\t\t\tdescription: \"Link a social account to the user\",\n\t\t\t\toperationId: \"linkSocialAccount\",\n\t\t\t\tresponses: {\n\t\t\t\t\t\"200\": {\n\t\t\t\t\t\tdescription: \"Success\",\n\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\turl: {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\"The authorization URL to redirect the user to\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tredirect: {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\"Indicates if the user should be redirected to the authorization URL\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tstatus: {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\trequired: [\"redirect\"],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t},\n\tasync (c) => {\n\t\tconst session = c.context.session;\n\n\t\tconst provider = c.context.socialProviders.find(\n\t\t\t(p) => p.id === c.body.provider,\n\t\t);\n\n\t\tif (!provider) {\n\t\t\tc.context.logger.error(\n\t\t\t\t\"Provider not found. Make sure to add the provider in your auth config\",\n\t\t\t\t{\n\t\t\t\t\tprovider: c.body.provider,\n\t\t\t\t},\n\t\t\t);\n\t\t\tthrow new APIError(\"NOT_FOUND\", {\n\t\t\t\tmessage: BASE_ERROR_CODES.PROVIDER_NOT_FOUND,\n\t\t\t});\n\t\t}\n\n\t\t// Handle ID Token flow if provided\n\t\tif (c.body.idToken) {\n\t\t\tif (!provider.verifyIdToken) {\n\t\t\t\tc.context.logger.error(\n\t\t\t\t\t\"Provider does not support id token verification\",\n\t\t\t\t\t{\n\t\t\t\t\t\tprovider: c.body.provider,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tthrow new APIError(\"NOT_FOUND\", {\n\t\t\t\t\tmessage: BASE_ERROR_CODES.ID_TOKEN_NOT_SUPPORTED,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst { token, nonce } = c.body.idToken;\n\t\t\tconst valid = await provider.verifyIdToken(token, nonce);\n\t\t\tif (!valid) {\n\t\t\t\tc.context.logger.error(\"Invalid id token\", {\n\t\t\t\t\tprovider: c.body.provider,\n\t\t\t\t});\n\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\tmessage: BASE_ERROR_CODES.INVALID_TOKEN,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst linkingUserInfo = await provider.getUserInfo({\n\t\t\t\tidToken: token,\n\t\t\t\taccessToken: c.body.idToken.accessToken,\n\t\t\t\trefreshToken: c.body.idToken.refreshToken,\n\t\t\t});\n\n\t\t\tif (!linkingUserInfo || !linkingUserInfo?.user) {\n\t\t\t\tc.context.logger.error(\"Failed to get user info\", {\n\t\t\t\t\tprovider: c.body.provider,\n\t\t\t\t});\n\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\tmessage: BASE_ERROR_CODES.FAILED_TO_GET_USER_INFO,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst linkingUserId = String(linkingUserInfo.user.id);\n\n\t\t\tif (!linkingUserInfo.user.email) {\n\t\t\t\tc.context.logger.error(\"User email not found\", {\n\t\t\t\t\tprovider: c.body.provider,\n\t\t\t\t});\n\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\tmessage: BASE_ERROR_CODES.USER_EMAIL_NOT_FOUND,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst existingAccounts = await c.context.internalAdapter.findAccounts(\n\t\t\t\tsession.user.id,\n\t\t\t);\n\n\t\t\tconst hasBeenLinked = existingAccounts.find(\n\t\t\t\t(a) => a.providerId === provider.id && a.accountId === linkingUserId,\n\t\t\t);\n\n\t\t\tif (hasBeenLinked) {\n\t\t\t\treturn c.json({\n\t\t\t\t\turl: \"\", // this is for type inference\n\t\t\t\t\tstatus: true,\n\t\t\t\t\tredirect: false,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst trustedProviders =\n\t\t\t\tc.context.options.account?.accountLinking?.trustedProviders;\n\n\t\t\tconst isTrustedProvider = trustedProviders?.includes(provider.id);\n\t\t\tif (\n\t\t\t\t(!isTrustedProvider && !linkingUserInfo.user.emailVerified) ||\n\t\t\t\tc.context.options.account?.accountLinking?.enabled === false\n\t\t\t) {\n\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\tmessage: \"Account not linked - linking not allowed\",\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tlinkingUserInfo.user.email !== session.user.email &&\n\t\t\t\tc.context.options.account?.accountLinking?.allowDifferentEmails !== true\n\t\t\t) {\n\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\tmessage: \"Account not linked - different emails not allowed\",\n\t\t\t\t});\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tawait c.context.internalAdapter.createAccount({\n\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\tproviderId: provider.id,\n\t\t\t\t\taccountId: linkingUserId,\n\t\t\t\t\taccessToken: c.body.idToken.accessToken,\n\t\t\t\t\tidToken: token,\n\t\t\t\t\trefreshToken: c.body.idToken.refreshToken,\n\t\t\t\t\tscope: c.body.idToken.scopes?.join(\",\"),\n\t\t\t\t});\n\t\t\t} catch {\n\t\t\t\tthrow new APIError(\"EXPECTATION_FAILED\", {\n\t\t\t\t\tmessage: \"Account not linked - unable to create account\",\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tc.context.options.account?.accountLinking?.updateUserInfoOnLink === true\n\t\t\t) {\n\t\t\t\ttry {\n\t\t\t\t\tawait c.context.internalAdapter.updateUser(session.user.id, {\n\t\t\t\t\t\tname: linkingUserInfo.user?.name,\n\t\t\t\t\t\timage: linkingUserInfo.user?.image,\n\t\t\t\t\t});\n\t\t\t\t} catch (e: any) {\n\t\t\t\t\tconsole.warn(\"Could not update user - \" + e.toString());\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn c.json({\n\t\t\t\turl: \"\", // this is for type inference\n\t\t\t\tstatus: true,\n\t\t\t\tredirect: false,\n\t\t\t});\n\t\t}\n\n\t\t// Handle OAuth flow\n\t\tconst state = await generateState(\n\t\t\tc,\n\t\t\t{\n\t\t\t\tuserId: session.user.id,\n\t\t\t\temail: session.user.email,\n\t\t\t},\n\t\t\tc.body.additionalData,\n\t\t);\n\n\t\tconst url = await provider.createAuthorizationURL({\n\t\t\tstate: state.state,\n\t\t\tcodeVerifier: state.codeVerifier,\n\t\t\tredirectURI: `${c.context.baseURL}/callback/${provider.id}`,\n\t\t\tscopes: c.body.scopes,\n\t\t});\n\n\t\treturn c.json({\n\t\t\turl: url.toString(),\n\t\t\tredirect: !c.body.disableRedirect,\n\t\t});\n\t},\n);\nexport const unlinkAccount = createAuthEndpoint(\n\t\"/unlink-account\",\n\t{\n\t\tmethod: \"POST\",\n\t\tbody: z.object({\n\t\t\tproviderId: z.string(),\n\t\t\taccountId: z.string().optional(),\n\t\t}),\n\t\tuse: [freshSessionMiddleware],\n\t\tmetadata: {\n\t\t\topenapi: {\n\t\t\t\tdescription: \"Unlink an account\",\n\t\t\t\tresponses: {\n\t\t\t\t\t\"200\": {\n\t\t\t\t\t\tdescription: \"Success\",\n\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\tstatus: {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t},\n\tasync (ctx) => {\n\t\tconst { providerId, accountId } = ctx.body;\n\t\tconst accounts = await ctx.context.internalAdapter.findAccounts(\n\t\t\tctx.context.session.user.id,\n\t\t);\n\t\tif (\n\t\t\taccounts.length === 1 &&\n\t\t\t!ctx.context.options.account?.accountLinking?.allowUnlinkingAll\n\t\t) {\n\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\tmessage: BASE_ERROR_CODES.FAILED_TO_UNLINK_LAST_ACCOUNT,\n\t\t\t});\n\t\t}\n\t\tconst accountExist = accounts.find((account) =>\n\t\t\taccountId\n\t\t\t\t? account.accountId === accountId && account.providerId === providerId\n\t\t\t\t: account.providerId === providerId,\n\t\t);\n\t\tif (!accountExist) {\n\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\tmessage: BASE_ERROR_CODES.ACCOUNT_NOT_FOUND,\n\t\t\t});\n\t\t}\n\t\tawait ctx.context.internalAdapter.deleteAccount(accountExist.id);\n\t\treturn ctx.json({\n\t\t\tstatus: true,\n\t\t});\n\t},\n);\n\nexport const getAccessToken = createAuthEndpoint(\n\t\"/get-access-token\",\n\t{\n\t\tmethod: \"POST\",\n\t\tbody: z.object({\n\t\t\tproviderId: z.string().meta({\n\t\t\t\tdescription: \"The provider ID for the OAuth provider\",\n\t\t\t}),\n\t\t\taccountId: z\n\t\t\t\t.string()\n\t\t\t\t.meta({\n\t\t\t\t\tdescription: \"The account ID associated with the refresh token\",\n\t\t\t\t})\n\t\t\t\t.optional(),\n\t\t\tuserId: z\n\t\t\t\t.string()\n\t\t\t\t.meta({\n\t\t\t\t\tdescription: \"The user ID associated with the account\",\n\t\t\t\t})\n\t\t\t\t.optional(),\n\t\t}),\n\t\tmetadata: {\n\t\t\topenapi: {\n\t\t\t\tdescription: \"Get a valid access token, doing a refresh if needed\",\n\t\t\t\tresponses: {\n\t\t\t\t\t200: {\n\t\t\t\t\t\tdescription: \"A Valid access token\",\n\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\ttokenType: {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tidToken: {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\taccessToken: {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\trefreshToken: {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\taccessTokenExpiresAt: {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\tformat: \"date-time\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\trefreshTokenExpiresAt: {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\tformat: \"date-time\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t400: {\n\t\t\t\t\t\tdescription: \"Invalid refresh token or provider configuration\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t},\n\tasync (ctx) => {\n\t\tconst { providerId, accountId, userId } = ctx.body || {};\n\t\tconst req = ctx.request;\n\t\tconst session = await getSessionFromCtx(ctx);\n\t\tif (req && !session) {\n\t\t\tthrow ctx.error(\"UNAUTHORIZED\");\n\t\t}\n\t\tlet resolvedUserId = session?.user?.id || userId;\n\t\tif (!resolvedUserId) {\n\t\t\tthrow ctx.error(\"UNAUTHORIZED\");\n\t\t}\n\t\tif (!ctx.context.socialProviders.find((p) => p.id === providerId)) {\n\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\tmessage: `Provider ${providerId} is not supported.`,\n\t\t\t});\n\t\t}\n\t\tconst accountData = await getAccountCookie(ctx);\n\t\tlet account: Account | undefined = undefined;\n\t\tif (\n\t\t\taccountData &&\n\t\t\tproviderId === accountData.providerId &&\n\t\t\t(!accountId || accountData.id === accountId)\n\t\t) {\n\t\t\taccount = accountData;\n\t\t} else {\n\t\t\tconst accounts =\n\t\t\t\tawait ctx.context.internalAdapter.findAccounts(resolvedUserId);\n\t\t\taccount = accounts.find((acc) =>\n\t\t\t\taccountId\n\t\t\t\t\t? acc.id === accountId && acc.providerId === providerId\n\t\t\t\t\t: acc.providerId === providerId,\n\t\t\t);\n\t\t}\n\n\t\tif (!account) {\n\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\tmessage: \"Account not found\",\n\t\t\t});\n\t\t}\n\t\tconst provider = ctx.context.socialProviders.find(\n\t\t\t(p) => p.id === providerId,\n\t\t);\n\t\tif (!provider) {\n\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\tmessage: `Provider ${providerId} not found.`,\n\t\t\t});\n\t\t}\n\n\t\ttry {\n\t\t\tlet newTokens: OAuth2Tokens | null = null;\n\t\t\tconst accessTokenExpired =\n\t\t\t\taccount.accessTokenExpiresAt &&\n\t\t\t\tnew Date(account.accessTokenExpiresAt).getTime() - Date.now() < 5_000;\n\t\t\tif (\n\t\t\t\taccount.refreshToken &&\n\t\t\t\taccessTokenExpired &&\n\t\t\t\tprovider.refreshAccessToken\n\t\t\t) {\n\t\t\t\tconst refreshToken = await decryptOAuthToken(\n\t\t\t\t\taccount.refreshToken,\n\t\t\t\t\tctx.context,\n\t\t\t\t);\n\t\t\t\tnewTokens = await provider.refreshAccessToken(refreshToken);\n\t\t\t\tconst updatedData = {\n\t\t\t\t\taccessToken: await setTokenUtil(newTokens.accessToken, ctx.context),\n\t\t\t\t\taccessTokenExpiresAt: newTokens.accessTokenExpiresAt,\n\t\t\t\t\trefreshToken: await setTokenUtil(newTokens.refreshToken, ctx.context),\n\t\t\t\t\trefreshTokenExpiresAt: newTokens.refreshTokenExpiresAt,\n\t\t\t\t};\n\t\t\t\tlet updatedAccount: Record<string, any> | null = null;\n\t\t\t\tif (account.id) {\n\t\t\t\t\tupdatedAccount = await ctx.context.internalAdapter.updateAccount(\n\t\t\t\t\t\taccount.id,\n\t\t\t\t\t\tupdatedData,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (ctx.context.options.account?.storeAccountCookie) {\n\t\t\t\t\tawait setAccountCookie(ctx, {\n\t\t\t\t\t\t...account,\n\t\t\t\t\t\t...(updatedAccount ?? updatedData),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst tokens = {\n\t\t\t\taccessToken:\n\t\t\t\t\tnewTokens?.accessToken ??\n\t\t\t\t\t(await decryptOAuthToken(account.accessToken ?? \"\", ctx.context)),\n\t\t\t\taccessTokenExpiresAt:\n\t\t\t\t\tnewTokens?.accessTokenExpiresAt ??\n\t\t\t\t\taccount.accessTokenExpiresAt ??\n\t\t\t\t\tundefined,\n\t\t\t\tscopes: account.scope?.split(\",\") ?? [],\n\t\t\t\tidToken: newTokens?.idToken ?? account.idToken ?? undefined,\n\t\t\t};\n\t\t\treturn ctx.json(tokens);\n\t\t} catch (error) {\n\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\tmessage: \"Failed to get a valid access token\",\n\t\t\t\tcause: error,\n\t\t\t});\n\t\t}\n\t},\n);\n\nexport const refreshToken = createAuthEndpoint(\n\t\"/refresh-token\",\n\t{\n\t\tmethod: \"POST\",\n\t\tbody: z.object({\n\t\t\tproviderId: z.string().meta({\n\t\t\t\tdescription: \"The provider ID for the OAuth provider\",\n\t\t\t}),\n\t\t\taccountId: z\n\t\t\t\t.string()\n\t\t\t\t.meta({\n\t\t\t\t\tdescription: \"The account ID associated with the refresh token\",\n\t\t\t\t})\n\t\t\t\t.optional(),\n\t\t\tuserId: z\n\t\t\t\t.string()\n\t\t\t\t.meta({\n\t\t\t\t\tdescription: \"The user ID associated with the account\",\n\t\t\t\t})\n\t\t\t\t.optional(),\n\t\t}),\n\t\tmetadata: {\n\t\t\topenapi: {\n\t\t\t\tdescription: \"Refresh the access token using a refresh token\",\n\t\t\t\tresponses: {\n\t\t\t\t\t200: {\n\t\t\t\t\t\tdescription: \"Access token refreshed successfully\",\n\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\ttokenType: {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tidToken: {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\taccessToken: {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\trefreshToken: {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\taccessTokenExpiresAt: {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\tformat: \"date-time\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\trefreshTokenExpiresAt: {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\tformat: \"date-time\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t400: {\n\t\t\t\t\t\tdescription: \"Invalid refresh token or provider configuration\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t},\n\tasync (ctx) => {\n\t\tconst { providerId, accountId, userId } = ctx.body;\n\t\tconst req = ctx.request;\n\t\tconst session = await getSessionFromCtx(ctx);\n\t\tif (req && !session) {\n\t\t\tthrow ctx.error(\"UNAUTHORIZED\");\n\t\t}\n\t\tlet resolvedUserId = session?.user?.id || userId;\n\t\tif (!resolvedUserId) {\n\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\tmessage: `Either userId or session is required`,\n\t\t\t});\n\t\t}\n\t\tconst provider = ctx.context.socialProviders.find(\n\t\t\t(p) => p.id === providerId,\n\t\t);\n\t\tif (!provider) {\n\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\tmessage: `Provider ${providerId} not found.`,\n\t\t\t});\n\t\t}\n\t\tif (!provider.refreshAccessToken) {\n\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\tmessage: `Provider ${providerId} does not support token refreshing.`,\n\t\t\t});\n\t\t}\n\n\t\t// Try to read refresh token from cookie first\n\t\tlet account: Account | undefined = undefined;\n\t\tconst accountData = await getAccountCookie(ctx);\n\t\tif (\n\t\t\taccountData &&\n\t\t\t(!providerId || providerId === accountData?.providerId)\n\t\t) {\n\t\t\taccount = accountData;\n\t\t} else {\n\t\t\tconst accounts =\n\t\t\t\tawait ctx.context.internalAdapter.findAccounts(resolvedUserId);\n\t\t\taccount = accounts.find((acc) =>\n\t\t\t\taccountId\n\t\t\t\t\t? acc.id === accountId && acc.providerId === providerId\n\t\t\t\t\t: acc.providerId === providerId,\n\t\t\t);\n\t\t}\n\n\t\tif (!account) {\n\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\tmessage: \"Account not found\",\n\t\t\t});\n\t\t}\n\n\t\tlet refreshToken: string | null | undefined = undefined;\n\t\tif (accountData && providerId === accountData.providerId) {\n\t\t\trefreshToken = accountData.refreshToken ?? undefined;\n\t\t} else {\n\t\t\trefreshToken = account.refreshToken ?? undefined;\n\t\t}\n\n\t\tif (!refreshToken) {\n\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\tmessage: \"Refresh token not found\",\n\t\t\t});\n\t\t}\n\n\t\ttry {\n\t\t\tconst decryptedRefreshToken = await decryptOAuthToken(\n\t\t\t\trefreshToken,\n\t\t\t\tctx.context,\n\t\t\t);\n\t\t\tconst tokens: OAuth2Tokens = await provider.refreshAccessToken(\n\t\t\t\tdecryptedRefreshToken,\n\t\t\t);\n\n\t\t\tif (account.id) {\n\t\t\t\tconst updateData = {\n\t\t\t\t\t...(account || {}),\n\t\t\t\t\taccessToken: await setTokenUtil(tokens.accessToken, ctx.context),\n\t\t\t\t\trefreshToken: await setTokenUtil(tokens.refreshToken, ctx.context),\n\t\t\t\t\taccessTokenExpiresAt: tokens.accessTokenExpiresAt,\n\t\t\t\t\trefreshTokenExpiresAt: tokens.refreshTokenExpiresAt,\n\t\t\t\t\tscope: tokens.scopes?.join(\",\") || account.scope,\n\t\t\t\t\tidToken: tokens.idToken || account.idToken,\n\t\t\t\t};\n\t\t\t\tawait ctx.context.internalAdapter.updateAccount(account.id, updateData);\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\taccountData &&\n\t\t\t\tproviderId === accountData.providerId &&\n\t\t\t\tctx.context.options.account?.storeAccountCookie\n\t\t\t) {\n\t\t\t\tconst updateData = {\n\t\t\t\t\t...accountData,\n\t\t\t\t\taccessToken: await setTokenUtil(tokens.accessToken, ctx.context),\n\t\t\t\t\trefreshToken: await setTokenUtil(tokens.refreshToken, ctx.context),\n\t\t\t\t\taccessTokenExpiresAt: tokens.accessTokenExpiresAt,\n\t\t\t\t\trefreshTokenExpiresAt: tokens.refreshTokenExpiresAt,\n\t\t\t\t\tscope: tokens.scopes?.join(\",\") || accountData.scope,\n\t\t\t\t\tidToken: tokens.idToken || accountData.idToken,\n\t\t\t\t};\n\t\t\t\tawait setAccountCookie(ctx, updateData);\n\t\t\t}\n\t\t\treturn ctx.json({\n\t\t\t\taccessToken: tokens.accessToken,\n\t\t\t\trefreshToken: tokens.refreshToken,\n\t\t\t\taccessTokenExpiresAt: tokens.accessTokenExpiresAt,\n\t\t\t\trefreshTokenExpiresAt: tokens.refreshTokenExpiresAt,\n\t\t\t\tscope: tokens.scopes?.join(\",\") || account.scope,\n\t\t\t\tidToken: tokens.idToken || account.idToken,\n\t\t\t\tproviderId: account.providerId,\n\t\t\t\taccountId: account.accountId,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\tmessage: \"Failed to refresh access token\",\n\t\t\t\tcause: error,\n\t\t\t});\n\t\t}\n\t},\n);\n\nconst accountInfoQuerySchema = z.optional(\n\tz.object({\n\t\taccountId: z\n\t\t\t.string()\n\t\t\t.meta({\n\t\t\t\tdescription:\n\t\t\t\t\t\"The provider given account id for which to get the account info\",\n\t\t\t})\n\t\t\t.optional(),\n\t}),\n);\n\nexport const accountInfo = createAuthEndpoint(\n\t\"/account-info\",\n\t{\n\t\tmethod: \"GET\",\n\t\tuse: [sessionMiddleware],\n\t\tmetadata: {\n\t\t\topenapi: {\n\t\t\t\tdescription: \"Get the account info provided by the provider\",\n\t\t\t\tresponses: {\n\t\t\t\t\t\"200\": {\n\t\t\t\t\t\tdescription: \"Success\",\n\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\tuser: {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\t\tid: {\n\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\tname: {\n\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\temail: {\n\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\timage: {\n\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\temailVerified: {\n\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\trequired: [\"id\", \"emailVerified\"],\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\t\tproperties: {},\n\t\t\t\t\t\t\t\t\t\t\tadditionalProperties: true,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\trequired: [\"user\", \"data\"],\n\t\t\t\t\t\t\t\t\tadditionalProperties: false,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tquery: accountInfoQuerySchema,\n\t},\n\tasync (ctx) => {\n\t\tconst providedAccountId = ctx.query?.accountId;\n\t\tlet account: Account | undefined = undefined;\n\t\tif (!providedAccountId) {\n\t\t\tif (ctx.context.options.account?.storeAccountCookie) {\n\t\t\t\tconst accountData = await getAccountCookie(ctx);\n\t\t\t\tif (accountData) {\n\t\t\t\t\taccount = accountData;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tconst accountData =\n\t\t\t\tawait ctx.context.internalAdapter.findAccount(providedAccountId);\n\t\t\tif (accountData) {\n\t\t\t\taccount = accountData;\n\t\t\t}\n\t\t}\n\n\t\tif (!account || account.userId !== ctx.context.session.user.id) {\n\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\tmessage: \"Account not found\",\n\t\t\t});\n\t\t}\n\n\t\tconst provider = ctx.context.socialProviders.find(\n\t\t\t(p) => p.id === account.providerId,\n\t\t);\n\n\t\tif (!provider) {\n\t\t\tthrow new APIError(\"INTERNAL_SERVER_ERROR\", {\n\t\t\t\tmessage: `Provider account provider is ${account.providerId} but it is not configured`,\n\t\t\t});\n\t\t}\n\t\tconst tokens = await getAccessToken({\n\t\t\t...ctx,\n\t\t\tmethod: \"POST\",\n\t\t\tbody: {\n\t\t\t\taccountId: account.id,\n\t\t\t\tproviderId: account.providerId,\n\t\t\t},\n\t\t\treturnHeaders: false,\n\t\t\treturnStatus: false,\n\t\t});\n\t\tif (!tokens.accessToken) {\n\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\tmessage: \"Access token not found\",\n\t\t\t});\n\t\t}\n\t\tconst info = await provider.getUserInfo({\n\t\t\t...tokens,\n\t\t\taccessToken: tokens.accessToken as string,\n\t\t});\n\t\treturn ctx.json(info);\n\t},\n);\n"],"mappings":"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"}