@payloadcms/figma 0.0.1-alpha.7 → 0.0.1-alpha.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/control-plane.d.ts +56 -6
- package/dist/api/control-plane.js +181 -72
- package/dist/api/figma-api.d.ts +22 -1
- package/dist/api/figma-api.js +78 -25
- package/dist/auth/callback-server.d.ts +19 -7
- package/dist/auth/callback-server.js +72 -30
- package/dist/auth/credentials.d.ts +21 -0
- package/dist/auth/credentials.js +21 -0
- package/dist/auth/crypto-utils.d.ts +28 -0
- package/dist/auth/crypto-utils.js +132 -21
- package/dist/auth/jwt-validator.d.ts +2 -1
- package/dist/auth/jwt-validator.js +2 -2
- package/dist/auth/oauth-flow.d.ts +19 -3
- package/dist/auth/oauth-flow.js +77 -22
- package/dist/auth/project-token.d.ts +32 -16
- package/dist/auth/project-token.js +171 -65
- package/dist/auth/refresh.d.ts +2 -1
- package/dist/auth/refresh.js +25 -12
- package/dist/auth/token-store-migration.d.ts +58 -0
- package/dist/auth/token-store-migration.js +156 -0
- package/dist/auth/token-store.d.ts +63 -97
- package/dist/auth/token-store.js +405 -122
- package/dist/auth/types.d.ts +35 -4
- package/dist/cli.js +93 -6
- package/dist/commands/bootstrap.d.ts +18 -0
- package/dist/commands/bootstrap.js +90 -0
- package/dist/commands/build-lambda-zip.d.ts +5 -0
- package/dist/commands/build-lambda-zip.js +19 -0
- package/dist/commands/debug.d.ts +8 -0
- package/dist/commands/debug.js +180 -0
- package/dist/commands/deploy.d.ts +9 -0
- package/dist/commands/deploy.js +180 -151
- package/dist/commands/dump-tokens.d.ts +12 -0
- package/dist/commands/dump-tokens.js +69 -0
- package/dist/commands/env.d.ts +13 -0
- package/dist/commands/env.js +88 -0
- package/dist/commands/init.d.ts +9 -5
- package/dist/commands/init.js +241 -148
- package/dist/commands/list-tokens.d.ts +3 -3
- package/dist/commands/list-tokens.js +24 -9
- package/dist/commands/login.d.ts +8 -1
- package/dist/commands/login.js +34 -16
- package/dist/commands/logout.d.ts +5 -4
- package/dist/commands/logout.js +77 -15
- package/dist/commands/upgrade.d.ts +5 -0
- package/dist/commands/upgrade.js +331 -0
- package/dist/config/oauth.d.ts +17 -11
- package/dist/config/oauth.js +38 -37
- package/dist/constants.d.ts +63 -18
- package/dist/constants.js +158 -18
- package/dist/db-content-api/generated/content-api-types.d.ts +3978 -0
- package/dist/db-content-api/generated/content-api-types.js +7 -0
- package/dist/db-content-api/index.d.ts +37 -0
- package/dist/db-content-api/index.js +923 -0
- package/dist/db-content-api/temp-utilities/slug.d.ts +2 -0
- package/dist/db-content-api/temp-utilities/slug.js +3 -0
- package/dist/db-content-api/temp-utilities/sorting.d.ts +3 -0
- package/dist/db-content-api/temp-utilities/sorting.js +39 -0
- package/dist/db-content-api/temp-utilities/types.d.ts +22 -0
- package/dist/db-content-api/temp-utilities/types.js +15 -0
- package/dist/db-content-api/temp-utilities/unwrapDocument.d.ts +39 -0
- package/dist/db-content-api/temp-utilities/unwrapDocument.js +64 -0
- package/dist/db-content-api/utilities/auth.d.ts +30 -0
- package/dist/db-content-api/utilities/auth.js +84 -0
- package/dist/db-content-api/utilities/data/applyDefaults.d.ts +7 -0
- package/dist/db-content-api/utilities/data/applyDefaults.js +75 -0
- package/dist/db-content-api/utilities/data/castFieldValue.d.ts +11 -0
- package/dist/db-content-api/utilities/data/castFieldValue.js +68 -0
- package/dist/db-content-api/utilities/data/index.d.ts +49 -0
- package/dist/db-content-api/utilities/data/index.js +301 -0
- package/dist/db-content-api/utilities/data/removeVirtualFields.d.ts +12 -0
- package/dist/db-content-api/utilities/data/removeVirtualFields.js +54 -0
- package/dist/db-content-api/utilities/data/stripFields.d.ts +48 -0
- package/dist/db-content-api/utilities/data/stripFields.js +195 -0
- package/dist/db-content-api/utilities/data/transformPublishedLocale.d.ts +23 -0
- package/dist/db-content-api/utilities/data/transformPublishedLocale.js +42 -0
- package/dist/db-content-api/utilities/data/validateRelationships.d.ts +7 -0
- package/dist/db-content-api/utilities/data/validateRelationships.js +102 -0
- package/dist/db-content-api/utilities/joins.d.ts +53 -0
- package/dist/db-content-api/utilities/joins.js +139 -0
- package/dist/db-content-api/utilities/locale/index.d.ts +10 -0
- package/dist/db-content-api/utilities/locale/index.js +21 -0
- package/dist/db-content-api/utilities/meta/buildLocalizedPaths.d.ts +11 -0
- package/dist/db-content-api/utilities/meta/buildLocalizedPaths.js +74 -0
- package/dist/db-content-api/utilities/meta/buildMeta.d.ts +42 -0
- package/dist/db-content-api/utilities/meta/buildMeta.js +41 -0
- package/dist/db-content-api/utilities/meta/buildPathTypes.d.ts +17 -0
- package/dist/db-content-api/utilities/meta/buildPathTypes.js +244 -0
- package/dist/db-content-api/utilities/meta/buildUniquePaths.d.ts +13 -0
- package/dist/db-content-api/utilities/meta/buildUniquePaths.js +62 -0
- package/dist/db-content-api/utilities/meta/normalizeLocaleInWhere.d.ts +10 -0
- package/dist/db-content-api/utilities/meta/normalizeLocaleInWhere.js +102 -0
- package/dist/db-content-api/utilities/where.d.ts +20 -0
- package/dist/db-content-api/utilities/where.js +108 -0
- package/dist/deploy/schedule-extract-plugin.d.ts +11 -0
- package/dist/deploy/schedule-extract-plugin.js +34 -0
- package/dist/endpoints/health.d.ts +3 -0
- package/dist/endpoints/health.js +11 -0
- package/dist/endpoints/schema.d.ts +3 -0
- package/dist/endpoints/schema.js +29 -0
- package/dist/exports/client.d.ts +3 -0
- package/dist/exports/client.js +3 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- package/dist/lib/download-skill.d.ts +13 -0
- package/dist/lib/download-skill.js +79 -0
- package/dist/oauth/components/FigmaAvatar/index.d.ts +4 -0
- package/dist/oauth/components/FigmaAvatar/index.js +27 -0
- package/dist/oauth/components/FigmaAvatar/index.scss +12 -0
- package/dist/oauth/components/FigmaAvatarCell/index.d.ts +5 -0
- package/dist/oauth/components/FigmaAvatarCell/index.js +25 -0
- package/dist/oauth/components/FigmaAvatarCell/index.scss +5 -0
- package/dist/oauth/components/FigmaAvatarPlaceholder/index.d.ts +9 -0
- package/dist/oauth/components/FigmaAvatarPlaceholder/index.js +37 -0
- package/dist/oauth/components/FigmaAvatarPlaceholder/index.scss +28 -0
- package/dist/oauth/components/LoginButton/iframeAutoLogin.d.ts +82 -0
- package/dist/oauth/components/LoginButton/iframeAutoLogin.js +170 -0
- package/dist/oauth/components/LoginButton/index.js +150 -12
- package/dist/oauth/components/LoginButton/index.scss +75 -3
- package/dist/oauth/components/LogoutButton/index.js +20 -7
- package/dist/oauth/defaults.d.ts +3 -1
- package/dist/oauth/defaults.js +68 -10
- package/dist/oauth/endpoints/getLoginEndpoint.js +72 -77
- package/dist/oauth/endpoints/getLogoutEndpoint.js +7 -4
- package/dist/oauth/endpoints/getMetaEndpoint.js +18 -3
- package/dist/oauth/endpoints/getRedirectToLoginEndpoint.js +11 -2
- package/dist/oauth/index.js +27 -5
- package/dist/oauth/strategy/index.d.ts +0 -2
- package/dist/oauth/strategy/index.js +40 -17
- package/dist/oauth/types.d.ts +23 -6
- package/dist/oauth/utilities/establishSession.d.ts +23 -0
- package/dist/oauth/utilities/establishSession.js +82 -0
- package/dist/oauth/utilities/exchangeCodeForAccessToken.d.ts +24 -0
- package/dist/oauth/utilities/exchangeCodeForAccessToken.js +28 -0
- package/dist/oauth/utilities/figmaHostnames.d.ts +3 -0
- package/dist/oauth/utilities/figmaHostnames.js +26 -0
- package/dist/oauth/utilities/getAuthorizeURL.d.ts +65 -1
- package/dist/oauth/utilities/getAuthorizeURL.js +57 -2
- package/dist/oauth/utilities/isAbsoluteURL.d.ts +2 -0
- package/dist/oauth/utilities/isAbsoluteURL.js +3 -0
- package/dist/oauth/utilities/isDuplicateKeyError.d.ts +7 -0
- package/dist/oauth/utilities/isDuplicateKeyError.js +14 -0
- package/dist/oauth/utilities/refreshTokens.js +6 -3
- package/dist/plugin/auth-preflight.d.ts +8 -0
- package/dist/plugin/auth-preflight.js +20 -0
- package/dist/plugin/bootstrap-preflight.d.ts +23 -0
- package/dist/plugin/bootstrap-preflight.js +45 -0
- package/dist/plugin/build-config.d.ts +27 -15
- package/dist/plugin/build-config.js +327 -17
- package/dist/plugin/dev-cookie-names.d.ts +14 -0
- package/dist/plugin/dev-cookie-names.js +19 -0
- package/dist/storage-content-api/api-types.d.ts +168 -0
- package/dist/storage-content-api/api-types.js +6 -0
- package/dist/storage-content-api/client-uploads/ClientUploadHandler.d.ts +9 -0
- package/dist/storage-content-api/client-uploads/ClientUploadHandler.js +43 -0
- package/dist/storage-content-api/client-uploads/generateSignedURL.d.ts +13 -0
- package/dist/storage-content-api/client-uploads/generateSignedURL.js +39 -0
- package/dist/storage-content-api/client.d.ts +6 -0
- package/dist/storage-content-api/client.js +39 -0
- package/dist/storage-content-api/generateURL.d.ts +7 -0
- package/dist/storage-content-api/generateURL.js +8 -0
- package/dist/storage-content-api/handleDelete.d.ts +8 -0
- package/dist/storage-content-api/handleDelete.js +17 -0
- package/dist/storage-content-api/handleUpload.d.ts +11 -0
- package/dist/storage-content-api/handleUpload.js +144 -0
- package/dist/storage-content-api/index.d.ts +5 -0
- package/dist/storage-content-api/index.js +31 -0
- package/dist/storage-content-api/staticHandler.d.ts +10 -0
- package/dist/storage-content-api/staticHandler.js +63 -0
- package/dist/storage-content-api/types.d.ts +10 -0
- package/dist/storage-content-api/types.js +3 -0
- package/dist/storage-content-api/utilities/getSafeFilename.d.ts +12 -0
- package/dist/storage-content-api/utilities/getSafeFilename.js +61 -0
- package/dist/storage-content-api/utilities/index.d.ts +3 -0
- package/dist/storage-content-api/utilities/index.js +4 -0
- package/dist/storage-content-api/utilities/parseClientUploadContext.d.ts +19 -0
- package/dist/storage-content-api/utilities/parseClientUploadContext.js +30 -0
- package/dist/templates/.env.example +5 -0
- package/dist/templates/README.md +19 -0
- package/dist/types/config.d.ts +2 -1
- package/dist/types/config.js +0 -2
- package/dist/types.d.ts +10 -1
- package/dist/utils/adapters/nextjs.d.ts +9 -0
- package/dist/utils/adapters/nextjs.js +64 -0
- package/dist/utils/adapters/nitro.d.ts +9 -0
- package/dist/utils/adapters/nitro.js +169 -0
- package/dist/utils/adapters/vite.d.ts +10 -0
- package/dist/utils/adapters/vite.js +33 -0
- package/dist/utils/asset-collection.d.ts +27 -6
- package/dist/utils/asset-collection.js +59 -30
- package/dist/utils/build-detection.d.ts +5 -11
- package/dist/utils/build-detection.js +74 -11
- package/dist/utils/build-lambda-zip.d.ts +16 -0
- package/dist/utils/build-lambda-zip.js +78 -0
- package/dist/utils/cache-bootstrap.d.ts +8 -0
- package/dist/utils/cache-bootstrap.js +18 -0
- package/dist/utils/config.js +1 -1
- package/dist/utils/deploy-adapter.d.ts +40 -0
- package/dist/utils/deploy-adapter.js +58 -0
- package/dist/utils/download-template.d.ts +9 -1
- package/dist/utils/download-template.js +24 -18
- package/dist/utils/env-management.d.ts +24 -7
- package/dist/utils/env-management.js +119 -64
- package/dist/utils/format-env-suffix.d.ts +12 -0
- package/dist/utils/format-env-suffix.js +13 -0
- package/dist/utils/formatter.js +23 -11
- package/dist/utils/fs-utils.d.ts +6 -0
- package/dist/utils/fs-utils.js +27 -0
- package/dist/utils/handle-upgrade.d.ts +9 -0
- package/dist/utils/handle-upgrade.js +41 -0
- package/dist/utils/lambda-config.d.ts +3 -1
- package/dist/utils/lambda-config.js +75 -78
- package/dist/utils/messages.d.ts +1 -2
- package/dist/utils/messages.js +39 -11
- package/dist/utils/package-manager.d.ts +24 -0
- package/dist/utils/package-manager.js +53 -0
- package/dist/utils/parse-template-spec.d.ts +12 -0
- package/dist/utils/parse-template-spec.js +62 -0
- package/dist/utils/payload-config-ast.d.ts +27 -6
- package/dist/utils/payload-config-ast.js +106 -58
- package/dist/utils/payload-config-finder.d.ts +2 -2
- package/dist/utils/payload-config-finder.js +48 -9
- package/dist/utils/payload-config-modifier.d.ts +1 -1
- package/dist/utils/payload-config-modifier.js +114 -66
- package/dist/utils/payload-package-check.d.ts +33 -2
- package/dist/utils/payload-package-check.js +129 -28
- package/dist/utils/project.d.ts +7 -2
- package/dist/utils/project.js +60 -32
- package/dist/utils/resolve-environment.d.ts +14 -0
- package/dist/utils/resolve-environment.js +31 -0
- package/dist/utils/s3-upload.d.ts +7 -2
- package/dist/utils/s3-upload.js +39 -6
- package/dist/utils/token-display.d.ts +5 -1
- package/dist/utils/token-display.js +49 -22
- package/dist/utils/typescript-validator.js +4 -6
- package/dist/utils/version-check.d.ts +3 -0
- package/dist/utils/version-check.js +38 -0
- package/package.json +44 -15
- package/dist/api/control-plane.d.ts.map +0 -1
- package/dist/api/control-plane.js.map +0 -1
- package/dist/api/figma-api.d.ts.map +0 -1
- package/dist/api/figma-api.js.map +0 -1
- package/dist/auth/browser.d.ts.map +0 -1
- package/dist/auth/browser.js.map +0 -1
- package/dist/auth/callback-server.d.ts.map +0 -1
- package/dist/auth/callback-server.js.map +0 -1
- package/dist/auth/crypto-utils.d.ts.map +0 -1
- package/dist/auth/crypto-utils.js.map +0 -1
- package/dist/auth/jwt-validator.d.ts.map +0 -1
- package/dist/auth/jwt-validator.js.map +0 -1
- package/dist/auth/oauth-flow.d.ts.map +0 -1
- package/dist/auth/oauth-flow.js.map +0 -1
- package/dist/auth/pkce.d.ts.map +0 -1
- package/dist/auth/pkce.js.map +0 -1
- package/dist/auth/project-token.d.ts.map +0 -1
- package/dist/auth/project-token.js.map +0 -1
- package/dist/auth/refresh.d.ts.map +0 -1
- package/dist/auth/refresh.js.map +0 -1
- package/dist/auth/token-store.d.ts.map +0 -1
- package/dist/auth/token-store.js.map +0 -1
- package/dist/auth/types.d.ts.map +0 -1
- package/dist/auth/types.js.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/commands/deploy.d.ts.map +0 -1
- package/dist/commands/deploy.js.map +0 -1
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/list-tokens.d.ts.map +0 -1
- package/dist/commands/list-tokens.js.map +0 -1
- package/dist/commands/login.d.ts.map +0 -1
- package/dist/commands/login.js.map +0 -1
- package/dist/commands/logout.d.ts.map +0 -1
- package/dist/commands/logout.js.map +0 -1
- package/dist/config/oauth.d.ts.map +0 -1
- package/dist/config/oauth.js.map +0 -1
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js.map +0 -1
- package/dist/exports/client.d.ts.map +0 -1
- package/dist/exports/client.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/oauth/components/LoginButton/index.d.ts.map +0 -1
- package/dist/oauth/components/LoginButton/index.js.map +0 -1
- package/dist/oauth/components/LogoutButton/index.d.ts.map +0 -1
- package/dist/oauth/components/LogoutButton/index.js.map +0 -1
- package/dist/oauth/defaults.d.ts.map +0 -1
- package/dist/oauth/defaults.js.map +0 -1
- package/dist/oauth/endpoints/getLoginEndpoint.d.ts.map +0 -1
- package/dist/oauth/endpoints/getLoginEndpoint.js.map +0 -1
- package/dist/oauth/endpoints/getLogoutEndpoint.d.ts.map +0 -1
- package/dist/oauth/endpoints/getLogoutEndpoint.js.map +0 -1
- package/dist/oauth/endpoints/getMetaEndpoint.d.ts.map +0 -1
- package/dist/oauth/endpoints/getMetaEndpoint.js.map +0 -1
- package/dist/oauth/endpoints/getRedirectToLoginEndpoint.d.ts.map +0 -1
- package/dist/oauth/endpoints/getRedirectToLoginEndpoint.js.map +0 -1
- package/dist/oauth/exports/client.d.ts.map +0 -1
- package/dist/oauth/exports/client.js.map +0 -1
- package/dist/oauth/hooks/afterLogout.d.ts.map +0 -1
- package/dist/oauth/hooks/afterLogout.js.map +0 -1
- package/dist/oauth/hooks/me.d.ts.map +0 -1
- package/dist/oauth/hooks/me.js.map +0 -1
- package/dist/oauth/hooks/refresh.d.ts.map +0 -1
- package/dist/oauth/hooks/refresh.js.map +0 -1
- package/dist/oauth/index.d.ts.map +0 -1
- package/dist/oauth/index.js.map +0 -1
- package/dist/oauth/strategy/index.d.ts.map +0 -1
- package/dist/oauth/strategy/index.js.map +0 -1
- package/dist/oauth/types.d.ts.map +0 -1
- package/dist/oauth/types.js.map +0 -1
- package/dist/oauth/utilities/clearCookie.d.ts.map +0 -1
- package/dist/oauth/utilities/clearCookie.js.map +0 -1
- package/dist/oauth/utilities/createCookieOptions.d.ts.map +0 -1
- package/dist/oauth/utilities/createCookieOptions.js.map +0 -1
- package/dist/oauth/utilities/createDebugLogger.d.ts.map +0 -1
- package/dist/oauth/utilities/createDebugLogger.js.map +0 -1
- package/dist/oauth/utilities/extractOrigin.d.ts.map +0 -1
- package/dist/oauth/utilities/extractOrigin.js.map +0 -1
- package/dist/oauth/utilities/getAdminCollectionSlug.d.ts.map +0 -1
- package/dist/oauth/utilities/getAdminCollectionSlug.js.map +0 -1
- package/dist/oauth/utilities/getAdminPath.d.ts +0 -8
- package/dist/oauth/utilities/getAdminPath.d.ts.map +0 -1
- package/dist/oauth/utilities/getAdminPath.js +0 -9
- package/dist/oauth/utilities/getAdminPath.js.map +0 -1
- package/dist/oauth/utilities/getAuthorizeURL.d.ts.map +0 -1
- package/dist/oauth/utilities/getAuthorizeURL.js.map +0 -1
- package/dist/oauth/utilities/getCookieExpiration.d.ts.map +0 -1
- package/dist/oauth/utilities/getCookieExpiration.js.map +0 -1
- package/dist/oauth/utilities/getSecondsFromTokenExp.d.ts.map +0 -1
- package/dist/oauth/utilities/getSecondsFromTokenExp.js.map +0 -1
- package/dist/oauth/utilities/getTokenExp.d.ts.map +0 -1
- package/dist/oauth/utilities/getTokenExp.js.map +0 -1
- package/dist/oauth/utilities/getUsernameField.d.ts.map +0 -1
- package/dist/oauth/utilities/getUsernameField.js.map +0 -1
- package/dist/oauth/utilities/hasUserTokenPropsChanged.d.ts.map +0 -1
- package/dist/oauth/utilities/hasUserTokenPropsChanged.js.map +0 -1
- package/dist/oauth/utilities/mergeHeaders.d.ts.map +0 -1
- package/dist/oauth/utilities/mergeHeaders.js.map +0 -1
- package/dist/oauth/utilities/refreshTokens.d.ts.map +0 -1
- package/dist/oauth/utilities/refreshTokens.js.map +0 -1
- package/dist/plugin/adapter.d.ts.map +0 -1
- package/dist/plugin/adapter.js.map +0 -1
- package/dist/plugin/build-config.d.ts.map +0 -1
- package/dist/plugin/build-config.js.map +0 -1
- package/dist/types/config.d.ts.map +0 -1
- package/dist/types/config.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/utils/asset-collection.d.ts.map +0 -1
- package/dist/utils/asset-collection.js.map +0 -1
- package/dist/utils/build-detection.d.ts.map +0 -1
- package/dist/utils/build-detection.js.map +0 -1
- package/dist/utils/config.d.ts.map +0 -1
- package/dist/utils/config.js.map +0 -1
- package/dist/utils/download-template.d.ts.map +0 -1
- package/dist/utils/download-template.js.map +0 -1
- package/dist/utils/env-management.d.ts.map +0 -1
- package/dist/utils/env-management.js.map +0 -1
- package/dist/utils/format.d.ts.map +0 -1
- package/dist/utils/format.js.map +0 -1
- package/dist/utils/formatter.d.ts.map +0 -1
- package/dist/utils/formatter.js.map +0 -1
- package/dist/utils/git.d.ts.map +0 -1
- package/dist/utils/git.js.map +0 -1
- package/dist/utils/is-debug.d.ts.map +0 -1
- package/dist/utils/is-debug.js.map +0 -1
- package/dist/utils/lambda-config.d.ts.map +0 -1
- package/dist/utils/lambda-config.js.map +0 -1
- package/dist/utils/log.d.ts.map +0 -1
- package/dist/utils/log.js.map +0 -1
- package/dist/utils/messages.d.ts.map +0 -1
- package/dist/utils/messages.js.map +0 -1
- package/dist/utils/package-manager.d.ts.map +0 -1
- package/dist/utils/package-manager.js.map +0 -1
- package/dist/utils/payload-config-ast.d.ts.map +0 -1
- package/dist/utils/payload-config-ast.js.map +0 -1
- package/dist/utils/payload-config-finder.d.ts.map +0 -1
- package/dist/utils/payload-config-finder.js.map +0 -1
- package/dist/utils/payload-config-modifier.d.ts.map +0 -1
- package/dist/utils/payload-config-modifier.js.map +0 -1
- package/dist/utils/payload-package-check.d.ts.map +0 -1
- package/dist/utils/payload-package-check.js.map +0 -1
- package/dist/utils/project.d.ts.map +0 -1
- package/dist/utils/project.js.map +0 -1
- package/dist/utils/s3-upload.d.ts.map +0 -1
- package/dist/utils/s3-upload.js.map +0 -1
- package/dist/utils/token-display.d.ts.map +0 -1
- package/dist/utils/token-display.js.map +0 -1
- package/dist/utils/typescript-validator.d.ts.map +0 -1
- package/dist/utils/typescript-validator.js.map +0 -1
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import { APIError,
|
|
2
|
-
import { getSafeRedirect } from 'payload/shared';
|
|
3
|
-
import { getProjectToken } from '../../api/figma-api.js';
|
|
4
|
-
import { createCookieOptions } from '../utilities/createCookieOptions.js';
|
|
1
|
+
import { APIError, parseCookies } from 'payload';
|
|
2
|
+
import { formatAdminURL, getSafeRedirect } from 'payload/shared';
|
|
5
3
|
import { createDebugLogger } from '../utilities/createDebugLogger.js';
|
|
4
|
+
import { establishSession } from '../utilities/establishSession.js';
|
|
5
|
+
import { exchangeCodeForAccessToken } from '../utilities/exchangeCodeForAccessToken.js';
|
|
6
6
|
import { extractOrigin } from '../utilities/extractOrigin.js';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
const isAbsoluteURL = (url)=>/^[a-z][a-z\d+.-]*:/.test(url);
|
|
7
|
+
import { buildCsrfCookieClearHeader, OAUTH_STATE_CSRF_COOKIE_NAME } from '../utilities/getAuthorizeURL.js';
|
|
8
|
+
import { isAbsoluteURL } from '../utilities/isAbsoluteURL.js';
|
|
10
9
|
export const getLoginEndpoint = ({ collection, collectionOptions, endpointSlug, pluginOptions, strategy })=>({
|
|
11
10
|
handler: async (req)=>{
|
|
12
11
|
const { config } = req.payload;
|
|
13
|
-
const
|
|
12
|
+
const adminRoute = config.routes?.admin || '/admin';
|
|
14
13
|
try {
|
|
15
14
|
await strategy.ensureMeta();
|
|
16
15
|
const path = req.pathname;
|
|
@@ -37,9 +36,26 @@ export const getLoginEndpoint = ({ collection, collectionOptions, endpointSlug,
|
|
|
37
36
|
}
|
|
38
37
|
const stateRaw = jsonBody.state;
|
|
39
38
|
const state = JSON.parse(Buffer.from(stateRaw, 'base64').toString('utf-8'));
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
// Resolve the post-login redirect base. This MUST match the precedence
|
|
40
|
+
// used when the OAuth `redirect_uri` is minted at `/meta`
|
|
41
|
+
// (`getAuthorizeURL`: redirectServerURL → config.serverURL →
|
|
42
|
+
// state.serverURL). `state.serverURL` is the iframe's untrusted
|
|
43
|
+
// `window.location.origin` (a `/meta` query param), so it must rank
|
|
44
|
+
// LAST: trusting it first lets the redirect target diverge from the
|
|
45
|
+
// server-configured origin — in the Make preview that origin is http
|
|
46
|
+
// (mixed content) and, more visibly, it isn't in Payload's auto-derived
|
|
47
|
+
// `config.csrf` allowlist (sanitizeConfig pushes `config.serverURL`),
|
|
48
|
+
// so the CSRF origin check below 403s the callback.
|
|
49
|
+
const redirectServerURL = pluginOptions.redirectServerURL || config.serverURL || state.serverURL;
|
|
50
|
+
let failedRedirect = formatAdminURL({
|
|
51
|
+
adminRoute,
|
|
52
|
+
path: '/login',
|
|
53
|
+
serverURL: redirectServerURL
|
|
54
|
+
});
|
|
55
|
+
let redirectToUse = formatAdminURL({
|
|
56
|
+
adminRoute,
|
|
57
|
+
serverURL: redirectServerURL
|
|
58
|
+
});
|
|
43
59
|
if (state.redirect) {
|
|
44
60
|
redirectToUse = state.redirect;
|
|
45
61
|
}
|
|
@@ -93,6 +109,16 @@ export const getLoginEndpoint = ({ collection, collectionOptions, endpointSlug,
|
|
|
93
109
|
req.payload.logger.error('Signature mismatch. Failing login and redirecting.');
|
|
94
110
|
return Response.redirect(failedRedirect);
|
|
95
111
|
}
|
|
112
|
+
// Verify CSRF cookie matches the nonce baked into state at /meta time.
|
|
113
|
+
// This is the browser-binding required by RFC 6749 §10.12 — without
|
|
114
|
+
// it, an attacker who mints (code, state) via /meta + consent could
|
|
115
|
+
// replay them into a victim's browser by URL.
|
|
116
|
+
const cookies = parseCookies(req.headers);
|
|
117
|
+
const cookieCsrf = cookies.get(OAUTH_STATE_CSRF_COOKIE_NAME);
|
|
118
|
+
if (!cookieCsrf || cookieCsrf !== state.csrf) {
|
|
119
|
+
req.payload.logger.error('CSRF cookie mismatch. Failing login and redirecting.');
|
|
120
|
+
return Response.redirect(failedRedirect);
|
|
121
|
+
}
|
|
96
122
|
if (!strategy.meta?.token_endpoint) {
|
|
97
123
|
debugLogger.error({
|
|
98
124
|
msg: `No metadata was obtained from the identity provider. Failing login and redirecting.`,
|
|
@@ -121,57 +147,27 @@ export const getLoginEndpoint = ({ collection, collectionOptions, endpointSlug,
|
|
|
121
147
|
});
|
|
122
148
|
return Response.redirect(failedRedirect);
|
|
123
149
|
}
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
redirect_uri: `${redirectDestination}${config?.routes?.api || '/api'}/${collection.slug}/${endpointSlug}/login`
|
|
130
|
-
};
|
|
150
|
+
const redirectUri = formatAdminURL({
|
|
151
|
+
apiRoute: config.routes?.api || '/api',
|
|
152
|
+
path: `/${collection.slug}/${endpointSlug}/login`,
|
|
153
|
+
serverURL: redirectServerURL
|
|
154
|
+
});
|
|
131
155
|
debugLogger.info({
|
|
132
156
|
msg: 'Exchanging code for access token',
|
|
133
|
-
path
|
|
134
|
-
|
|
157
|
+
path
|
|
158
|
+
});
|
|
159
|
+
const tokenRes = await exchangeCodeForAccessToken({
|
|
160
|
+
code,
|
|
161
|
+
codeVerifier: req.payload.decrypt(state.verifier),
|
|
162
|
+
redirectUri,
|
|
163
|
+
strategy
|
|
135
164
|
});
|
|
136
|
-
if (strategy.clientSecret) {
|
|
137
|
-
body.client_secret = strategy.clientSecret;
|
|
138
|
-
}
|
|
139
|
-
const tokenRes = await fetch(strategy.meta?.token_endpoint, {
|
|
140
|
-
body: new URLSearchParams(body),
|
|
141
|
-
headers: {
|
|
142
|
-
'Content-Type': 'application/x-www-form-urlencoded'
|
|
143
|
-
},
|
|
144
|
-
method: 'POST'
|
|
145
|
-
}).then((r)=>r.json());
|
|
146
165
|
debugLogger.info({
|
|
147
166
|
msg: 'Token Response',
|
|
148
167
|
path,
|
|
149
168
|
tokenRes
|
|
150
169
|
});
|
|
151
170
|
const { access_token, error, error_description, expires_in: refreshTokenExpires } = tokenRes;
|
|
152
|
-
debugLogger.info({
|
|
153
|
-
msg: 'tokenResss',
|
|
154
|
-
tokenRes
|
|
155
|
-
});
|
|
156
|
-
// Swap for project token
|
|
157
|
-
const project_token = await getProjectToken(tokenRes.access_token, 'someproject');
|
|
158
|
-
const refresh_token = access_token;
|
|
159
|
-
// Store project token as access_token
|
|
160
|
-
const token = project_token.token;
|
|
161
|
-
const expiresIn = project_token.expiresAt;
|
|
162
|
-
if (!token) {
|
|
163
|
-
const errMsg = `No ${collectionOptions.token || 'access_token'} was returned from the identity provider.`;
|
|
164
|
-
req.payload.logger.error({
|
|
165
|
-
msg: errMsg,
|
|
166
|
-
path
|
|
167
|
-
});
|
|
168
|
-
throw new APIError(errMsg);
|
|
169
|
-
}
|
|
170
|
-
const cookieOptions = createCookieOptions({
|
|
171
|
-
collection,
|
|
172
|
-
headers: req.headers,
|
|
173
|
-
pluginOptions
|
|
174
|
-
});
|
|
175
171
|
if (error) {
|
|
176
172
|
req.payload.logger.error('Error swapping access code with access token:');
|
|
177
173
|
req.payload.logger.error({
|
|
@@ -180,12 +176,22 @@ export const getLoginEndpoint = ({ collection, collectionOptions, endpointSlug,
|
|
|
180
176
|
});
|
|
181
177
|
return Response.redirect(failedRedirect);
|
|
182
178
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
179
|
+
if (!access_token) {
|
|
180
|
+
const errMsg = 'No access_token was returned from the identity provider.';
|
|
181
|
+
req.payload.logger.error({
|
|
182
|
+
msg: errMsg,
|
|
183
|
+
path,
|
|
184
|
+
tokenRes
|
|
185
|
+
});
|
|
186
|
+
throw new APIError(errMsg);
|
|
187
|
+
}
|
|
188
|
+
const payloadRedirect = cookies.get('payloadRedirect') ?? '';
|
|
186
189
|
if (!req.responseHeaders) {
|
|
187
190
|
req.responseHeaders = new Headers();
|
|
188
191
|
}
|
|
192
|
+
// Clear the CSRF cookie now that the flow has completed — the nonce
|
|
193
|
+
// is single-use; leaving it around lets a replay try again.
|
|
194
|
+
req.responseHeaders.append('Set-Cookie', buildCsrfCookieClearHeader());
|
|
189
195
|
if (payloadRedirect) {
|
|
190
196
|
if (isAbsoluteURL(payloadRedirect)) {
|
|
191
197
|
redirectToUse = payloadRedirect;
|
|
@@ -194,28 +200,17 @@ export const getLoginEndpoint = ({ collection, collectionOptions, endpointSlug,
|
|
|
194
200
|
}
|
|
195
201
|
req.responseHeaders.append('Set-Cookie', `payloadRedirect=${redirectToUse}; Max-Age=0; Path=/;`);
|
|
196
202
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
req.responseHeaders.append('Set-Cookie', refreshCookie);
|
|
208
|
-
}
|
|
209
|
-
const tokenExpires = cookieOptions?.expires ? getCookieExpiration(cookieOptions.expires) : new Date(expiresIn) // Project token uses epoch time
|
|
210
|
-
;
|
|
211
|
-
const tokenCookie = generateCookie({
|
|
212
|
-
...cookieOptions,
|
|
213
|
-
name: strategy.cookieName,
|
|
214
|
-
expires: tokenExpires,
|
|
215
|
-
returnCookieAsObject: false,
|
|
216
|
-
value: token
|
|
203
|
+
await establishSession({
|
|
204
|
+
accessToken: access_token,
|
|
205
|
+
collection,
|
|
206
|
+
collectionOptions,
|
|
207
|
+
contentSystemId: config.custom.figma.contentSystemId,
|
|
208
|
+
debugLogger,
|
|
209
|
+
pluginOptions,
|
|
210
|
+
refreshTokenExpiresIn: refreshTokenExpires,
|
|
211
|
+
req,
|
|
212
|
+
strategy
|
|
217
213
|
});
|
|
218
|
-
req.responseHeaders.append('Set-Cookie', tokenCookie);
|
|
219
214
|
return Response.redirect(redirectToUse);
|
|
220
215
|
} catch (err) {
|
|
221
216
|
req.payload.logger.error({
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import jwt from 'jsonwebtoken';
|
|
2
2
|
import { parseCookies } from 'payload';
|
|
3
|
+
import { formatAdminURL } from 'payload/shared';
|
|
3
4
|
import { clearCookie } from '../utilities/clearCookie.js';
|
|
4
5
|
import { createCookieOptions } from '../utilities/createCookieOptions.js';
|
|
5
6
|
import { createDebugLogger } from '../utilities/createDebugLogger.js';
|
|
6
|
-
import { getAdminPath } from '../utilities/getAdminPath.js';
|
|
7
7
|
export const getLogoutEndpoint = ({ collection, endpointSlug, pluginOptions, strategy })=>({
|
|
8
8
|
handler: async (req)=>{
|
|
9
9
|
const debugLogger = createDebugLogger(req.payload, pluginOptions.debug);
|
|
@@ -23,12 +23,15 @@ export const getLogoutEndpoint = ({ collection, endpointSlug, pluginOptions, str
|
|
|
23
23
|
}
|
|
24
24
|
try {
|
|
25
25
|
await strategy.ensureMeta();
|
|
26
|
-
const
|
|
27
|
-
let successfulLogoutRedirectDest =
|
|
26
|
+
const redirectServerlURL = pluginOptions.redirectServerURL || config.serverURL;
|
|
27
|
+
let successfulLogoutRedirectDest = formatAdminURL({
|
|
28
|
+
adminRoute: config.routes?.admin || '/admin',
|
|
29
|
+
serverURL: redirectServerlURL
|
|
30
|
+
});
|
|
28
31
|
if (typeof req.query.redirect === 'string') {
|
|
29
32
|
successfulLogoutRedirectDest = req.query.redirect;
|
|
30
33
|
}
|
|
31
|
-
if (!
|
|
34
|
+
if (!redirectServerlURL && !req.query.redirect) {
|
|
32
35
|
debugLogger.error({
|
|
33
36
|
msg: 'No redirect URL provided',
|
|
34
37
|
path: req.pathname
|
|
@@ -1,10 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { parseCookies } from 'payload';
|
|
2
|
+
import { buildCsrfCookieHeader, getAuthorizeURL, OAUTH_STATE_CSRF_COOKIE_NAME } from '../utilities/getAuthorizeURL.js';
|
|
2
3
|
export const getMetaEndpoint = ({ collection, collectionOptions, endpointSlug, pluginOptions, strategy })=>({
|
|
3
4
|
handler: async (req)=>{
|
|
4
|
-
|
|
5
|
+
// Reuse the CSRF nonce from the existing cookie if one is set. Makes
|
|
6
|
+
// `/meta` idempotent: a second call from the same browser (Strict Mode
|
|
7
|
+
// re-mount, retry, multi-tab) returns the SAME state.csrf, so the
|
|
8
|
+
// cookie never has to change after the first call — no last-write-wins
|
|
9
|
+
// race between the cookie and the iframe's already-captured state.
|
|
10
|
+
const existingCsrfNonce = parseCookies(req.headers).get(OAUTH_STATE_CSRF_COOKIE_NAME);
|
|
11
|
+
const { authorizeURL, csrfNonce, params } = await getAuthorizeURL({
|
|
5
12
|
collection,
|
|
6
13
|
collectionOptions,
|
|
7
14
|
endpointSlug,
|
|
15
|
+
existingCsrfNonce,
|
|
8
16
|
failedRedirect: req.query.failedRedirect,
|
|
9
17
|
payload: req.payload,
|
|
10
18
|
pluginOptions,
|
|
@@ -12,8 +20,15 @@ export const getMetaEndpoint = ({ collection, collectionOptions, endpointSlug, p
|
|
|
12
20
|
serverURLOverride: req.query.serverURL,
|
|
13
21
|
strategy
|
|
14
22
|
});
|
|
23
|
+
if (!req.responseHeaders) {
|
|
24
|
+
req.responseHeaders = new Headers();
|
|
25
|
+
}
|
|
26
|
+
// Always re-emit Set-Cookie — when reusing, this just refreshes Max-Age
|
|
27
|
+
// so long-lived tabs don't expire the cookie mid-consent.
|
|
28
|
+
req.responseHeaders.append('Set-Cookie', buildCsrfCookieHeader(csrfNonce));
|
|
15
29
|
return Response.json({
|
|
16
|
-
authorizeURL
|
|
30
|
+
authorizeURL,
|
|
31
|
+
params
|
|
17
32
|
}, {
|
|
18
33
|
status: 200
|
|
19
34
|
});
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { parseCookies } from 'payload';
|
|
2
|
+
import { buildCsrfCookieHeader, getAuthorizeURL, OAUTH_STATE_CSRF_COOKIE_NAME } from '../utilities/getAuthorizeURL.js';
|
|
2
3
|
export const getRedirectToLoginEndpoint = ({ collection, collectionOptions, endpointSlug, pluginOptions, strategy })=>({
|
|
3
4
|
handler: async (req)=>{
|
|
4
|
-
|
|
5
|
+
// Reuse the CSRF nonce from the existing cookie if one is set. See
|
|
6
|
+
// getMetaEndpoint.ts for the idempotency rationale.
|
|
7
|
+
const existingCsrfNonce = parseCookies(req.headers).get(OAUTH_STATE_CSRF_COOKIE_NAME);
|
|
8
|
+
const { authorizeURL, csrfNonce } = await getAuthorizeURL({
|
|
5
9
|
collection,
|
|
6
10
|
collectionOptions,
|
|
7
11
|
endpointSlug,
|
|
12
|
+
existingCsrfNonce,
|
|
8
13
|
failedRedirect: req.query.failedRedirect,
|
|
9
14
|
payload: req.payload,
|
|
10
15
|
pluginOptions,
|
|
@@ -12,6 +17,10 @@ export const getRedirectToLoginEndpoint = ({ collection, collectionOptions, endp
|
|
|
12
17
|
serverURLOverride: req.query.serverURL,
|
|
13
18
|
strategy
|
|
14
19
|
});
|
|
20
|
+
if (!req.responseHeaders) {
|
|
21
|
+
req.responseHeaders = new Headers();
|
|
22
|
+
}
|
|
23
|
+
req.responseHeaders.append('Set-Cookie', buildCsrfCookieHeader(csrfNonce));
|
|
15
24
|
return Response.redirect(authorizeURL);
|
|
16
25
|
},
|
|
17
26
|
method: 'get',
|
package/dist/oauth/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { fieldAffectsData } from 'payload/shared';
|
|
1
2
|
import { defaultVerify } from './defaults.js';
|
|
2
3
|
import { getLoginEndpoint } from './endpoints/getLoginEndpoint.js';
|
|
3
4
|
import { getLogoutEndpoint } from './endpoints/getLogoutEndpoint.js';
|
|
@@ -94,7 +95,12 @@ export const oAuth2Plugin = (pluginOptions)=>(config)=>{
|
|
|
94
95
|
...existingCollection.fields,
|
|
95
96
|
{
|
|
96
97
|
name: 'email',
|
|
97
|
-
type: 'email'
|
|
98
|
+
type: 'email',
|
|
99
|
+
admin: {
|
|
100
|
+
description: 'Managed by Figma',
|
|
101
|
+
readOnly: true
|
|
102
|
+
},
|
|
103
|
+
unique: true
|
|
98
104
|
}
|
|
99
105
|
]
|
|
100
106
|
};
|
|
@@ -102,10 +108,22 @@ export const oAuth2Plugin = (pluginOptions)=>(config)=>{
|
|
|
102
108
|
collection: collectionWithEmail,
|
|
103
109
|
collectionOptions
|
|
104
110
|
});
|
|
111
|
+
// Make username field readOnly (and add description for email fields)
|
|
112
|
+
const readOnlyUsernameField = {
|
|
113
|
+
...usernameField,
|
|
114
|
+
admin: {
|
|
115
|
+
...usernameField.admin || {},
|
|
116
|
+
...usernameField.name === 'email' ? {
|
|
117
|
+
description: 'Managed by Figma'
|
|
118
|
+
} : {},
|
|
119
|
+
readOnly: true
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
const isUsernameFieldString = typeof adminCollectionOptions.usernameField === 'string';
|
|
105
123
|
const fields = [
|
|
106
|
-
...collectionWithEmail.fields,
|
|
107
|
-
...
|
|
108
|
-
|
|
124
|
+
...collectionWithEmail.fields.map((field)=>fieldAffectsData(field) && field.name === usernameField.name ? readOnlyUsernameField : field),
|
|
125
|
+
...isUsernameFieldString ? [] : [
|
|
126
|
+
readOnlyUsernameField
|
|
109
127
|
]
|
|
110
128
|
];
|
|
111
129
|
if (disabled) {
|
|
@@ -116,7 +134,6 @@ export const oAuth2Plugin = (pluginOptions)=>(config)=>{
|
|
|
116
134
|
}
|
|
117
135
|
const strategy = new Strategy({
|
|
118
136
|
clientID: collectionOptions.clientID,
|
|
119
|
-
clientSecret: collectionOptions.clientSecret,
|
|
120
137
|
collection: existingCollection,
|
|
121
138
|
collectionOptions,
|
|
122
139
|
cookieName,
|
|
@@ -127,6 +144,7 @@ export const oAuth2Plugin = (pluginOptions)=>(config)=>{
|
|
|
127
144
|
verify: collectionOptions.verify ?? defaultVerify({
|
|
128
145
|
collection: existingCollection,
|
|
129
146
|
strategyName,
|
|
147
|
+
userInfoCookieName: pluginOptions?.userInfoCookieName,
|
|
130
148
|
usernameField
|
|
131
149
|
})
|
|
132
150
|
});
|
|
@@ -148,6 +166,10 @@ export const oAuth2Plugin = (pluginOptions)=>(config)=>{
|
|
|
148
166
|
}
|
|
149
167
|
return {
|
|
150
168
|
...existingCollection,
|
|
169
|
+
access: {
|
|
170
|
+
...existingCollection.access || {},
|
|
171
|
+
create: ()=>false
|
|
172
|
+
},
|
|
151
173
|
auth: {
|
|
152
174
|
...typeof existingCollection.auth === 'object' ? existingCollection.auth : {},
|
|
153
175
|
disableLocalStrategy,
|
|
@@ -4,7 +4,6 @@ import * as jose from 'jose';
|
|
|
4
4
|
import type { CollectionOptions, PluginOptions, VerifyFunction } from '../types.js';
|
|
5
5
|
export interface Options {
|
|
6
6
|
clientID: string;
|
|
7
|
-
clientSecret?: string;
|
|
8
7
|
collection: CollectionConfig;
|
|
9
8
|
collectionOptions: CollectionOptions;
|
|
10
9
|
cookieName: string;
|
|
@@ -16,7 +15,6 @@ export interface Options {
|
|
|
16
15
|
}
|
|
17
16
|
export declare class Strategy {
|
|
18
17
|
clientID: string;
|
|
19
|
-
clientSecret?: string;
|
|
20
18
|
collection: CollectionConfig;
|
|
21
19
|
collectionOptions: CollectionOptions;
|
|
22
20
|
cookieName: string;
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import * as jose from 'jose';
|
|
2
2
|
import { APIError, parseCookies } from 'payload';
|
|
3
|
-
import { validateProjectToken } from '../../auth/jwt-validator.js';
|
|
4
|
-
import {
|
|
3
|
+
import { JWTValidationError, validateProjectToken } from '../../auth/jwt-validator.js';
|
|
4
|
+
import { getInfraEnvironment } from '../../constants.js';
|
|
5
5
|
import { createDebugLogger } from '../utilities/createDebugLogger.js';
|
|
6
6
|
import { getTokenExp } from '../utilities/getTokenExp.js';
|
|
7
7
|
import { mergeHeaders } from '../utilities/mergeHeaders.js';
|
|
8
8
|
import { refreshTokens } from '../utilities/refreshTokens.js';
|
|
9
9
|
export class Strategy {
|
|
10
10
|
clientID;
|
|
11
|
-
clientSecret;
|
|
12
11
|
collection;
|
|
13
12
|
collectionOptions;
|
|
14
13
|
cookieName;
|
|
@@ -28,7 +27,6 @@ export class Strategy {
|
|
|
28
27
|
this.verify = options.verify;
|
|
29
28
|
this.cookieName = options.cookieName;
|
|
30
29
|
this.clientID = options.clientID;
|
|
31
|
-
this.clientSecret = options.clientSecret;
|
|
32
30
|
this.identityMetadataURL = options.identityMetadata;
|
|
33
31
|
this.name = options.strategyName;
|
|
34
32
|
this.collection = options.collection;
|
|
@@ -63,7 +61,11 @@ export class Strategy {
|
|
|
63
61
|
}
|
|
64
62
|
}
|
|
65
63
|
if (!oauthToken) {
|
|
66
|
-
|
|
64
|
+
// Attempt refresh even when canSetHeaders=false (e.g., during RSC navigation).
|
|
65
|
+
// This allows authentication to succeed for the current request even when
|
|
66
|
+
// cookies cannot be updated. The cookie will be refreshed on the next
|
|
67
|
+
// full page load when canSetHeaders=true.
|
|
68
|
+
if (refreshToken) {
|
|
67
69
|
debugLogger.info({
|
|
68
70
|
msg: 'No access token found, but refresh token exists. Attempting to refresh...',
|
|
69
71
|
refreshToken
|
|
@@ -83,11 +85,20 @@ export class Strategy {
|
|
|
83
85
|
msg: 'Token refreshed. Verifying...',
|
|
84
86
|
verifyResult
|
|
85
87
|
});
|
|
86
|
-
|
|
87
|
-
|
|
88
|
+
// Only return response headers (to set cookies) when canSetHeaders is true.
|
|
89
|
+
// During RSC navigation, canSetHeaders=false because response streaming
|
|
90
|
+
// has already started and cookies cannot be modified.
|
|
91
|
+
if (canSetHeaders) {
|
|
92
|
+
if (verifyResult.responseHeaders) {
|
|
93
|
+
mergeHeaders(verifyResult.responseHeaders, refreshed.headers);
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
responseHeaders: refreshed.headers,
|
|
97
|
+
user: verifyResult.user
|
|
98
|
+
};
|
|
88
99
|
}
|
|
100
|
+
// Authenticate this request without updating cookies
|
|
89
101
|
return {
|
|
90
|
-
responseHeaders: refreshed.headers,
|
|
91
102
|
user: verifyResult.user
|
|
92
103
|
};
|
|
93
104
|
} else {
|
|
@@ -97,11 +108,10 @@ export class Strategy {
|
|
|
97
108
|
refreshToken
|
|
98
109
|
});
|
|
99
110
|
}
|
|
100
|
-
} else {
|
|
101
|
-
return {
|
|
102
|
-
user: null
|
|
103
|
-
};
|
|
104
111
|
}
|
|
112
|
+
return {
|
|
113
|
+
user: null
|
|
114
|
+
};
|
|
105
115
|
}
|
|
106
116
|
let oauthTokenVerifyResult = null;
|
|
107
117
|
// First, try to verify token
|
|
@@ -136,7 +146,10 @@ export class Strategy {
|
|
|
136
146
|
});
|
|
137
147
|
}
|
|
138
148
|
}
|
|
139
|
-
|
|
149
|
+
// Handle expired access token with valid refresh token.
|
|
150
|
+
// Same pattern as above: refresh regardless of canSetHeaders to support RSC navigation,
|
|
151
|
+
// but only update cookies when canSetHeaders=true.
|
|
152
|
+
if (oauthTokenVerifyResult instanceof JWTValidationError && oauthTokenVerifyResult.code === 'EXPIRED' && refreshToken && !this.collectionOptions.usePayloadJWT) {
|
|
140
153
|
const refreshed = await refreshTokens({
|
|
141
154
|
payload,
|
|
142
155
|
refreshToken,
|
|
@@ -157,11 +170,17 @@ export class Strategy {
|
|
|
157
170
|
msg: 'Token refreshed. Verifying...',
|
|
158
171
|
verifyResult
|
|
159
172
|
});
|
|
160
|
-
if (
|
|
161
|
-
|
|
173
|
+
if (canSetHeaders) {
|
|
174
|
+
if (verifyResult.responseHeaders) {
|
|
175
|
+
mergeHeaders(verifyResult.responseHeaders, refreshed.headers);
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
responseHeaders: refreshed.headers,
|
|
179
|
+
user: verifyResult.user
|
|
180
|
+
};
|
|
162
181
|
}
|
|
182
|
+
// Authenticate this request without updating cookies
|
|
163
183
|
return {
|
|
164
|
-
responseHeaders: refreshed.headers,
|
|
165
184
|
user: verifyResult.user
|
|
166
185
|
};
|
|
167
186
|
} else {
|
|
@@ -200,6 +219,10 @@ export class Strategy {
|
|
|
200
219
|
for(let attempt = 1; attempt <= 5; attempt++){
|
|
201
220
|
try {
|
|
202
221
|
this.meta = await fetch(this.identityMetadataURL).then((res)=>res.json());
|
|
222
|
+
if (this.meta) {
|
|
223
|
+
// TODO: This is a hack to get the DefaultLoginButton to work with dynamic OAuth client registration
|
|
224
|
+
this.meta.authorization_endpoint = this.meta?.authorization_endpoint + '/cms';
|
|
225
|
+
}
|
|
203
226
|
this.debugLog(`fetchMeta - success on attempt ${attempt}`);
|
|
204
227
|
if (this.meta?.jwks_uri) {
|
|
205
228
|
this.jwks = await fetch(this.meta.jwks_uri).then((res)=>res.json());
|
|
@@ -259,7 +282,7 @@ export class Strategy {
|
|
|
259
282
|
}
|
|
260
283
|
async jwtVerify({ payload, token }) {
|
|
261
284
|
try {
|
|
262
|
-
const verified = await validateProjectToken(token,
|
|
285
|
+
const verified = await validateProjectToken(token, getInfraEnvironment());
|
|
263
286
|
if (typeof verified !== 'string') {
|
|
264
287
|
return verified;
|
|
265
288
|
}
|
package/dist/oauth/types.d.ts
CHANGED
|
@@ -30,7 +30,7 @@ export interface CollectionOptions {
|
|
|
30
30
|
* Set to false to only accept the JWT from cookies
|
|
31
31
|
*/
|
|
32
32
|
disableJWTFromHeader?: boolean;
|
|
33
|
-
disableLocalStrategy?:
|
|
33
|
+
disableLocalStrategy?: false | IncomingAuthType['disableLocalStrategy'];
|
|
34
34
|
/**
|
|
35
35
|
* The logout button will either redirect to the IDP logout screen or
|
|
36
36
|
* automatically log the user out of the IDP depending on provider.
|
|
@@ -112,11 +112,6 @@ export interface PluginOptions {
|
|
|
112
112
|
* @default 'payload-oauth-token'
|
|
113
113
|
*/
|
|
114
114
|
cookieName?: string;
|
|
115
|
-
/**
|
|
116
|
-
* Debug mode will log additional information to the console.
|
|
117
|
-
*
|
|
118
|
-
* NOTE: This will log sensitive information to the console.
|
|
119
|
-
*/
|
|
120
115
|
/**
|
|
121
116
|
* Accepts incoming request and allows for modification of cookie options
|
|
122
117
|
*/
|
|
@@ -125,6 +120,11 @@ export interface PluginOptions {
|
|
|
125
120
|
cookieOptions: CookieOptions;
|
|
126
121
|
headers: Headers;
|
|
127
122
|
}) => CookieOptions;
|
|
123
|
+
/**
|
|
124
|
+
* Debug mode will log additional information to the console.
|
|
125
|
+
*
|
|
126
|
+
* NOTE: This will log sensitive information to the console.
|
|
127
|
+
*/
|
|
128
128
|
debug?: boolean;
|
|
129
129
|
/**
|
|
130
130
|
* Disables the plugin functionality while leaving in types, fields and component modifications.
|
|
@@ -148,6 +148,16 @@ export interface PluginOptions {
|
|
|
148
148
|
* @default 'oauth'
|
|
149
149
|
*/
|
|
150
150
|
strategyName?: string;
|
|
151
|
+
/**
|
|
152
|
+
* The name of the short-lived cookie used to carry Figma user profile
|
|
153
|
+
* info from the login endpoint to `defaultVerify`.
|
|
154
|
+
*
|
|
155
|
+
* Override in local dev when running multiple Payload apps on localhost
|
|
156
|
+
* to avoid cookie collisions (all localhost apps share a cookie jar).
|
|
157
|
+
*
|
|
158
|
+
* @default 'figma-user-info'
|
|
159
|
+
*/
|
|
160
|
+
userInfoCookieName?: string;
|
|
151
161
|
}
|
|
152
162
|
export type CookieOptions = {
|
|
153
163
|
domain?: string;
|
|
@@ -159,6 +169,13 @@ export type CookieOptions = {
|
|
|
159
169
|
secure?: boolean;
|
|
160
170
|
};
|
|
161
171
|
export type StateObj = {
|
|
172
|
+
/**
|
|
173
|
+
* Random per-flow nonce. The server sets a matching HttpOnly cookie
|
|
174
|
+
* (`payload-oauth-state_csrf`) at the time the state is minted; `/sso/login`
|
|
175
|
+
* compares the value in state to the cookie on callback. This is the
|
|
176
|
+
* browser-bound CSRF defense required by RFC 6749 §10.12.
|
|
177
|
+
*/
|
|
178
|
+
csrf: string;
|
|
162
179
|
/**
|
|
163
180
|
* Redirect to use if the login fails
|
|
164
181
|
*/
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { CollectionConfig, PayloadRequest } from 'payload';
|
|
2
|
+
import type { Strategy } from '../strategy/index.js';
|
|
3
|
+
import type { CollectionOptions, DebugLogger, PluginOptions } from '../types.js';
|
|
4
|
+
interface Args {
|
|
5
|
+
accessToken: string;
|
|
6
|
+
collection: CollectionConfig;
|
|
7
|
+
collectionOptions: CollectionOptions;
|
|
8
|
+
contentSystemId: string;
|
|
9
|
+
debugLogger: DebugLogger;
|
|
10
|
+
pluginOptions: PluginOptions;
|
|
11
|
+
/** From the IdP token response (`expires_in`); used as a refresh-cookie expiry fallback. */
|
|
12
|
+
refreshTokenExpiresIn?: number;
|
|
13
|
+
req: PayloadRequest;
|
|
14
|
+
strategy: Strategy;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Given a valid OAuth access_token: fetch user info (non-fatal), mint a
|
|
18
|
+
* project token, and write the main + refresh + user-info cookies to
|
|
19
|
+
* `req.responseHeaders`. Throws `APIError` if the project token mint fails.
|
|
20
|
+
*/
|
|
21
|
+
export declare const establishSession: ({ accessToken, collection, collectionOptions, contentSystemId, debugLogger, pluginOptions, refreshTokenExpiresIn, req, strategy, }: Args) => Promise<void>;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=establishSession.d.ts.map
|