@lucidcms/core
Version:
The core of the Lucid CMS. It's responsible for spinning up the API and serving the CMS.
1 lines • 8.15 kB
Source Map (JSON)
{"version":3,"file":"verify-token.mjs","names":["constants","authServices.refreshToken.clearToken","authServices.accessToken.clearToken"],"sources":["../../../../src/services/auth/refresh-token/verify-token.ts"],"sourcesContent":["import { getCookie } from \"hono/cookie\";\nimport { verify } from \"hono/jwt\";\nimport constants from \"../../../constants/constants.js\";\nimport createServiceContext from \"../../../libs/http/utils/create-service-context.js\";\nimport { copy } from \"../../../libs/i18n/index.js\";\nimport cacheKeys from \"../../../libs/kv/cache-keys.js\";\nimport { UserTokensRepository } from \"../../../libs/repositories/index.js\";\nimport type { LucidHonoContext } from \"../../../types/hono.js\";\nimport hashUserToken from \"../../../utils/helpers/hash-user-token.js\";\nimport type { ServiceResponse } from \"../../../utils/services/types.js\";\nimport { authServices } from \"../../index.js\";\nimport revokeUserTokens from \"./revoke-user-tokens.js\";\n\nconst verifyToken = async (\n\tc: LucidHonoContext,\n): ServiceResponse<{\n\tuser_id: number;\n}> => {\n\tconst config = c.get(\"config\");\n\n\ttry {\n\t\tconst _refresh = getCookie(c, constants.cookies.refreshToken);\n\n\t\tif (!_refresh) {\n\t\t\treturn {\n\t\t\t\terror: {\n\t\t\t\t\ttype: \"authorisation\",\n\t\t\t\t\tname: copy(\"server:core.auth.refresh.token.error.name\"),\n\t\t\t\t\tmessage: copy(\"server:core.auth.refresh.token.missing\"),\n\t\t\t\t},\n\t\t\t\tdata: undefined,\n\t\t\t};\n\t\t}\n\n\t\tconst UserTokens = new UserTokensRepository(\n\t\t\tc.get(\"database\").client,\n\t\t\tconfig.db,\n\t\t);\n\n\t\tconst decode = (await verify(\n\t\t\t_refresh,\n\t\t\tconfig.secrets.refreshToken,\n\t\t\tconstants.jwt.algorithm,\n\t\t)) as {\n\t\t\tid: number;\n\t\t};\n\t\tconst hashedRefreshToken = hashUserToken(_refresh);\n\n\t\tconst tokenRes = await UserTokens.selectSingle({\n\t\t\tselect: [\n\t\t\t\t\"user_id\",\n\t\t\t\t\"expiry_date\",\n\t\t\t\t\"revoked_at\",\n\t\t\t\t\"revoke_reason\",\n\t\t\t\t\"replaced_by_token_id\",\n\t\t\t],\n\t\t\twhere: [\n\t\t\t\t{\n\t\t\t\t\tkey: \"token\",\n\t\t\t\t\toperator: \"=\",\n\t\t\t\t\tvalue: hashedRefreshToken,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tkey: \"token_type\",\n\t\t\t\t\toperator: \"=\",\n\t\t\t\t\tvalue: constants.userTokens.refresh,\n\t\t\t\t},\n\t\t\t],\n\t\t});\n\t\tif (tokenRes.error) return tokenRes;\n\n\t\tif (!tokenRes.data || tokenRes.data.user_id !== decode.id) {\n\t\t\treturn {\n\t\t\t\terror: {\n\t\t\t\t\ttype: \"authorisation\",\n\t\t\t\t\tname: copy(\"server:core.auth.refresh.token.error.name\"),\n\t\t\t\t\tmessage: copy(\"server:core.auth.refresh.token.missing\"),\n\t\t\t\t},\n\t\t\t\tdata: undefined,\n\t\t\t};\n\t\t}\n\n\t\tif (tokenRes.data.revoked_at !== null) {\n\t\t\tif (tokenRes.data.replaced_by_token_id !== null) {\n\t\t\t\tawait revokeUserTokens(createServiceContext(c), {\n\t\t\t\t\tuserId: tokenRes.data.user_id,\n\t\t\t\t\trevokeReason: constants.refreshTokenRevokeReasons.reuseDetected,\n\t\t\t\t});\n\n\t\t\t\tconst [refreshRes, accessRes] = await Promise.all([\n\t\t\t\t\tauthServices.refreshToken.clearToken(c, {\n\t\t\t\t\t\trevokeReason: constants.refreshTokenRevokeReasons.reuseDetected,\n\t\t\t\t\t}),\n\t\t\t\t\tauthServices.accessToken.clearToken(c),\n\t\t\t\t]);\n\t\t\t\tif (refreshRes.error) return refreshRes;\n\t\t\t\tif (accessRes.error) return accessRes;\n\n\t\t\t\treturn {\n\t\t\t\t\terror: {\n\t\t\t\t\t\ttype: \"authorisation\",\n\t\t\t\t\t\tname: copy(\"server:core.auth.refresh.token.error.name\"),\n\t\t\t\t\t\tmessage: copy(\"server:core.auth.refresh.token.error.message\"),\n\t\t\t\t\t},\n\t\t\t\t\tdata: undefined,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\terror: {\n\t\t\t\t\ttype: \"authorisation\",\n\t\t\t\t\tname: copy(\"server:core.auth.refresh.token.error.name\"),\n\t\t\t\t\tmessage: copy(\"server:core.auth.refresh.token.missing\"),\n\t\t\t\t},\n\t\t\t\tdata: undefined,\n\t\t\t};\n\t\t}\n\n\t\tif (!tokenRes.data.expiry_date) {\n\t\t\treturn {\n\t\t\t\terror: {\n\t\t\t\t\ttype: \"authorisation\",\n\t\t\t\t\tname: copy(\"server:core.auth.refresh.token.error.name\"),\n\t\t\t\t\tmessage: copy(\"server:core.auth.refresh.token.missing\"),\n\t\t\t\t},\n\t\t\t\tdata: undefined,\n\t\t\t};\n\t\t}\n\n\t\tconst expiryMs = new Date(tokenRes.data.expiry_date).getTime();\n\t\tif (Number.isNaN(expiryMs) || expiryMs <= Date.now()) {\n\t\t\treturn {\n\t\t\t\terror: {\n\t\t\t\t\ttype: \"authorisation\",\n\t\t\t\t\tname: copy(\"server:core.auth.refresh.token.error.name\"),\n\t\t\t\t\tmessage: copy(\"server:core.auth.refresh.token.missing\"),\n\t\t\t\t},\n\t\t\t\tdata: undefined,\n\t\t\t};\n\t\t}\n\n\t\tconst context = createServiceContext(c);\n\t\tconst kv = context.kv;\n\t\tconst kvEntry = await kv.get<{ user_id: number }>(context, {\n\t\t\tkey: cacheKeys.auth.refresh(_refresh),\n\t\t\thash: true,\n\t\t});\n\n\t\tif (kvEntry && kvEntry.user_id === tokenRes.data.user_id) {\n\t\t\treturn {\n\t\t\t\terror: undefined,\n\t\t\t\tdata: { user_id: kvEntry.user_id },\n\t\t\t};\n\t\t}\n\n\t\tawait kv.set(context, {\n\t\t\tkey: cacheKeys.auth.refresh(_refresh),\n\t\t\tvalue: { user_id: tokenRes.data.user_id },\n\t\t\texpirationTtl: constants.refreshTokenExpiration,\n\t\t\thash: true,\n\t\t});\n\n\t\treturn {\n\t\t\terror: undefined,\n\t\t\tdata: {\n\t\t\t\tuser_id: tokenRes.data.user_id,\n\t\t\t},\n\t\t};\n\t} catch (_err) {\n\t\tconst [refreshRes, accessRes] = await Promise.all([\n\t\t\tauthServices.refreshToken.clearToken(c),\n\t\t\tauthServices.accessToken.clearToken(c),\n\t\t]);\n\t\tif (refreshRes.error) return refreshRes;\n\t\tif (accessRes.error) return accessRes;\n\n\t\treturn {\n\t\t\terror: {\n\t\t\t\ttype: \"authorisation\",\n\t\t\t\tname: copy(\"server:core.auth.refresh.token.error.name\"),\n\t\t\t\tmessage: copy(\"server:core.auth.refresh.token.error.message\"),\n\t\t\t},\n\t\t\tdata: undefined,\n\t\t};\n\t}\n};\n\nexport default verifyToken;\n"],"mappings":"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"}