@payloadcms/figma 0.0.1-alpha.9 → 0.1.0-alpha.1
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 -7
- package/dist/api/control-plane.js +188 -74
- package/dist/api/error-response.d.ts +36 -0
- package/dist/api/error-response.js +66 -0
- package/dist/api/figma-api.d.ts +24 -3
- package/dist/api/figma-api.js +110 -34
- package/dist/auth/browser.d.ts +0 -1
- package/dist/auth/browser.js +0 -2
- package/dist/auth/callback-server.d.ts +19 -8
- package/dist/auth/callback-server.js +72 -32
- package/dist/auth/credentials.d.ts +20 -0
- package/dist/auth/credentials.js +19 -0
- package/dist/auth/crypto-utils.d.ts +28 -1
- package/dist/auth/crypto-utils.js +132 -23
- package/dist/auth/jwt-validator.d.ts +23 -6
- package/dist/auth/jwt-validator.js +35 -9
- package/dist/auth/oauth-flow.d.ts +19 -4
- package/dist/auth/oauth-flow.js +151 -34
- package/dist/auth/paste-code.d.ts +33 -0
- package/dist/auth/paste-code.js +87 -0
- package/dist/auth/pkce.d.ts +0 -1
- package/dist/auth/pkce.js +0 -2
- package/dist/auth/project-token.d.ts +32 -17
- package/dist/auth/project-token.js +176 -68
- package/dist/auth/refresh.d.ts +2 -2
- package/dist/auth/refresh.js +25 -14
- package/dist/auth/token-store-migration.d.ts +57 -0
- package/dist/auth/token-store-migration.js +154 -0
- package/dist/auth/token-store.d.ts +63 -98
- package/dist/auth/token-store.js +405 -124
- package/dist/auth/types.d.ts +40 -6
- package/dist/auth/types.js +1 -3
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +102 -8
- package/dist/commands/bootstrap.d.ts +17 -0
- package/dist/commands/bootstrap.js +88 -0
- package/dist/commands/build-lambda-zip.d.ts +4 -0
- package/dist/commands/build-lambda-zip.js +17 -0
- package/dist/commands/debug.d.ts +7 -0
- package/dist/commands/debug.js +178 -0
- package/dist/commands/deploy.d.ts +11 -1
- package/dist/commands/deploy.js +193 -153
- package/dist/commands/dump-tokens.d.ts +11 -0
- package/dist/commands/dump-tokens.js +67 -0
- package/dist/commands/env.d.ts +12 -0
- package/dist/commands/env.js +86 -0
- package/dist/commands/init.d.ts +9 -6
- package/dist/commands/init.js +232 -152
- package/dist/commands/list-tokens.d.ts +3 -4
- package/dist/commands/list-tokens.js +24 -11
- package/dist/commands/login.d.ts +8 -2
- package/dist/commands/login.js +34 -18
- package/dist/commands/logout.d.ts +5 -5
- package/dist/commands/logout.js +77 -17
- package/dist/commands/upgrade.d.ts +4 -0
- package/dist/commands/upgrade.js +329 -0
- package/dist/commands/upload-schema.d.ts +8 -0
- package/dist/commands/upload-schema.js +91 -0
- package/dist/config/oauth.d.ts +17 -12
- package/dist/config/oauth.js +38 -39
- package/dist/constants.d.ts +63 -19
- package/dist/constants.js +158 -20
- package/dist/db-content-api/generated/content-api-types.d.ts +8215 -0
- package/dist/db-content-api/generated/content-api-types.js +5 -0
- package/dist/db-content-api/index.d.ts +40 -0
- package/dist/db-content-api/index.js +883 -0
- package/dist/db-content-api/temp-utilities/slug.d.ts +1 -0
- package/dist/db-content-api/temp-utilities/slug.js +1 -0
- package/dist/db-content-api/temp-utilities/sorting.d.ts +2 -0
- package/dist/db-content-api/temp-utilities/sorting.js +37 -0
- package/dist/db-content-api/temp-utilities/types.d.ts +21 -0
- package/dist/db-content-api/temp-utilities/types.js +13 -0
- package/dist/db-content-api/temp-utilities/unwrapDocument.d.ts +38 -0
- package/dist/db-content-api/temp-utilities/unwrapDocument.js +62 -0
- package/dist/db-content-api/utilities/auth.d.ts +29 -0
- package/dist/db-content-api/utilities/auth.js +82 -0
- package/dist/db-content-api/utilities/clientVersionHeaders.d.ts +7 -0
- package/dist/db-content-api/utilities/clientVersionHeaders.js +15 -0
- package/dist/db-content-api/utilities/data/applyDefaults.d.ts +6 -0
- package/dist/db-content-api/utilities/data/applyDefaults.js +75 -0
- package/dist/db-content-api/utilities/data/atomicOperations.d.ts +16 -0
- package/dist/db-content-api/utilities/data/atomicOperations.js +48 -0
- package/dist/db-content-api/utilities/data/castFieldValue.d.ts +10 -0
- package/dist/db-content-api/utilities/data/castFieldValue.js +66 -0
- package/dist/db-content-api/utilities/data/convertRelationshipIds.d.ts +25 -0
- package/dist/db-content-api/utilities/data/convertRelationshipIds.js +109 -0
- package/dist/db-content-api/utilities/data/index.d.ts +48 -0
- package/dist/db-content-api/utilities/data/index.js +315 -0
- package/dist/db-content-api/utilities/data/isLocaleMap.d.ts +10 -0
- package/dist/db-content-api/utilities/data/isLocaleMap.js +13 -0
- package/dist/db-content-api/utilities/data/pointShape.d.ts +3 -0
- package/dist/db-content-api/utilities/data/pointShape.js +43 -0
- package/dist/db-content-api/utilities/data/removeVirtualFields.d.ts +11 -0
- package/dist/db-content-api/utilities/data/removeVirtualFields.js +52 -0
- package/dist/db-content-api/utilities/data/resolveFieldLocalization.d.ts +18 -0
- package/dist/db-content-api/utilities/data/resolveFieldLocalization.js +21 -0
- package/dist/db-content-api/utilities/data/richTextShape.d.ts +3 -0
- package/dist/db-content-api/utilities/data/richTextShape.js +56 -0
- package/dist/db-content-api/utilities/data/stripFields.d.ts +47 -0
- package/dist/db-content-api/utilities/data/stripFields.js +170 -0
- package/dist/db-content-api/utilities/data/transformPublishedLocale.d.ts +22 -0
- package/dist/db-content-api/utilities/data/transformPublishedLocale.js +40 -0
- package/dist/db-content-api/utilities/data/validateRelationships.d.ts +6 -0
- package/dist/db-content-api/utilities/data/validateRelationships.js +107 -0
- package/dist/db-content-api/utilities/joins.d.ts +50 -0
- package/dist/db-content-api/utilities/joins.js +124 -0
- package/dist/db-content-api/utilities/locale/index.d.ts +9 -0
- package/dist/db-content-api/utilities/locale/index.js +19 -0
- package/dist/db-content-api/utilities/meta/normalizeLocaleInWhere.d.ts +9 -0
- package/dist/db-content-api/utilities/meta/normalizeLocaleInWhere.js +100 -0
- package/dist/db-content-api/utilities/resolveBlocks.d.ts +19 -0
- package/dist/db-content-api/utilities/resolveBlocks.js +31 -0
- package/dist/db-content-api/utilities/schema/buildDocumentSchema.d.ts +72 -0
- package/dist/db-content-api/utilities/schema/buildDocumentSchema.js +264 -0
- package/dist/db-content-api/utilities/where.d.ts +9 -0
- package/dist/db-content-api/utilities/where.js +95 -0
- package/dist/deploy/schedule-extract-plugin.d.ts +10 -0
- package/dist/deploy/schedule-extract-plugin.js +32 -0
- package/dist/endpoints/health.d.ts +2 -0
- package/dist/endpoints/health.js +9 -0
- package/dist/endpoints/schema.d.ts +2 -0
- package/dist/endpoints/schema.js +27 -0
- package/dist/exports/client.d.ts +2 -1
- package/dist/exports/client.js +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/lib/download-skill.d.ts +12 -0
- package/dist/lib/download-skill.js +77 -0
- package/dist/oauth/components/FigmaAvatar/index.d.ts +3 -0
- package/dist/oauth/components/FigmaAvatar/index.js +25 -0
- package/dist/oauth/components/FigmaAvatar/index.scss +12 -0
- package/dist/oauth/components/FigmaAvatarCell/index.d.ts +4 -0
- package/dist/oauth/components/FigmaAvatarCell/index.js +23 -0
- package/dist/oauth/components/FigmaAvatarCell/index.scss +5 -0
- package/dist/oauth/components/FigmaAvatarPlaceholder/index.d.ts +8 -0
- package/dist/oauth/components/FigmaAvatarPlaceholder/index.js +35 -0
- package/dist/oauth/components/FigmaAvatarPlaceholder/index.scss +28 -0
- package/dist/oauth/components/LoginButton/iframeAutoLogin.d.ts +81 -0
- package/dist/oauth/components/LoginButton/iframeAutoLogin.js +168 -0
- package/dist/oauth/components/LoginButton/index.d.ts +0 -1
- package/dist/oauth/components/LoginButton/index.js +156 -18
- package/dist/oauth/components/LoginButton/index.scss +75 -3
- package/dist/oauth/components/LogoutButton/index.d.ts +0 -1
- package/dist/oauth/components/LogoutButton/index.js +20 -9
- package/dist/oauth/defaults.d.ts +3 -2
- package/dist/oauth/defaults.js +79 -12
- package/dist/oauth/endpoints/getLoginEndpoint.d.ts +0 -1
- package/dist/oauth/endpoints/getLoginEndpoint.js +87 -84
- package/dist/oauth/endpoints/getLogoutEndpoint.d.ts +0 -1
- package/dist/oauth/endpoints/getLogoutEndpoint.js +7 -6
- package/dist/oauth/endpoints/getMetaEndpoint.d.ts +0 -1
- package/dist/oauth/endpoints/getMetaEndpoint.js +18 -5
- package/dist/oauth/endpoints/getRedirectToLoginEndpoint.d.ts +0 -1
- package/dist/oauth/endpoints/getRedirectToLoginEndpoint.js +11 -4
- package/dist/oauth/exports/client.d.ts +0 -1
- package/dist/oauth/exports/client.js +0 -2
- package/dist/oauth/hooks/afterLogout.d.ts +0 -1
- package/dist/oauth/hooks/afterLogout.js +0 -2
- package/dist/oauth/hooks/me.d.ts +0 -1
- package/dist/oauth/hooks/me.js +0 -2
- package/dist/oauth/hooks/refresh.d.ts +0 -1
- package/dist/oauth/hooks/refresh.js +2 -3
- package/dist/oauth/index.d.ts +0 -1
- package/dist/oauth/index.js +27 -7
- package/dist/oauth/strategy/index.d.ts +0 -3
- package/dist/oauth/strategy/index.js +55 -34
- package/dist/oauth/types.d.ts +23 -7
- package/dist/oauth/types.js +0 -2
- package/dist/oauth/utilities/buildUnauthorizedRedirect.d.ts +14 -0
- package/dist/oauth/utilities/buildUnauthorizedRedirect.js +28 -0
- package/dist/oauth/utilities/clearCookie.d.ts +0 -1
- package/dist/oauth/utilities/clearCookie.js +5 -3
- package/dist/oauth/utilities/createCookieOptions.d.ts +0 -1
- package/dist/oauth/utilities/createCookieOptions.js +9 -4
- package/dist/oauth/utilities/createDebugLogger.d.ts +0 -1
- package/dist/oauth/utilities/createDebugLogger.js +0 -2
- package/dist/oauth/utilities/establishSession.d.ts +22 -0
- package/dist/oauth/utilities/establishSession.js +80 -0
- package/dist/oauth/utilities/exchangeCodeForAccessToken.d.ts +23 -0
- package/dist/oauth/utilities/exchangeCodeForAccessToken.js +26 -0
- package/dist/oauth/utilities/extractOrigin.d.ts +0 -1
- package/dist/oauth/utilities/extractOrigin.js +0 -2
- package/dist/oauth/utilities/figmaHostnames.d.ts +2 -0
- package/dist/oauth/utilities/figmaHostnames.js +24 -0
- package/dist/oauth/utilities/getAdminCollectionSlug.d.ts +0 -1
- package/dist/oauth/utilities/getAdminCollectionSlug.js +0 -2
- package/dist/oauth/utilities/getAuthorizeURL.d.ts +65 -2
- package/dist/oauth/utilities/getAuthorizeURL.js +57 -4
- package/dist/oauth/utilities/getCookieExpiration.d.ts +0 -1
- package/dist/oauth/utilities/getCookieExpiration.js +0 -2
- package/dist/oauth/utilities/getSecondsFromTokenExp.d.ts +0 -1
- package/dist/oauth/utilities/getSecondsFromTokenExp.js +0 -2
- package/dist/oauth/utilities/getTokenExp.d.ts +0 -1
- package/dist/oauth/utilities/getTokenExp.js +0 -2
- package/dist/oauth/utilities/getUsernameField.d.ts +0 -1
- package/dist/oauth/utilities/getUsernameField.js +0 -2
- package/dist/oauth/utilities/hasUserTokenPropsChanged.d.ts +0 -1
- package/dist/oauth/utilities/hasUserTokenPropsChanged.js +0 -2
- package/dist/oauth/utilities/isAbsoluteURL.d.ts +1 -0
- package/dist/oauth/utilities/isAbsoluteURL.js +1 -0
- package/dist/oauth/utilities/isDuplicateKeyError.d.ts +6 -0
- package/dist/oauth/utilities/isDuplicateKeyError.js +12 -0
- package/dist/oauth/utilities/mergeHeaders.d.ts +0 -1
- package/dist/oauth/utilities/mergeHeaders.js +0 -2
- package/dist/oauth/utilities/refreshTokens.d.ts +0 -1
- package/dist/oauth/utilities/refreshTokens.js +21 -13
- package/dist/oauth/utilities/withPartitionedCookie.d.ts +19 -0
- package/dist/oauth/utilities/withPartitionedCookie.js +26 -0
- package/dist/oauth/utils/getSearchParam.d.ts +17 -0
- package/dist/oauth/utils/getSearchParam.js +22 -0
- package/dist/plugin/adapter.d.ts +0 -1
- package/dist/plugin/adapter.js +0 -2
- package/dist/plugin/auth-preflight.d.ts +7 -0
- package/dist/plugin/auth-preflight.js +18 -0
- package/dist/plugin/bootstrap-preflight.d.ts +22 -0
- package/dist/plugin/bootstrap-preflight.js +43 -0
- package/dist/plugin/build-config.d.ts +27 -15
- package/dist/plugin/build-config.js +380 -16
- package/dist/plugin/dev-cookie-names.d.ts +13 -0
- package/dist/plugin/dev-cookie-names.js +17 -0
- package/dist/scss.d.js +2 -0
- package/dist/storage-content-api/api-types.d.ts +183 -0
- package/dist/storage-content-api/api-types.js +4 -0
- package/dist/storage-content-api/client-uploads/generate.d.ts +14 -0
- package/dist/storage-content-api/client-uploads/generate.js +69 -0
- package/dist/storage-content-api/client.d.ts +5 -0
- package/dist/storage-content-api/client.js +37 -0
- package/dist/storage-content-api/generateURL.d.ts +6 -0
- package/dist/storage-content-api/generateURL.js +6 -0
- package/dist/storage-content-api/handleDelete.d.ts +7 -0
- package/dist/storage-content-api/handleDelete.js +15 -0
- package/dist/storage-content-api/handleUpload.d.ts +10 -0
- package/dist/storage-content-api/handleUpload.js +162 -0
- package/dist/storage-content-api/index.d.ts +4 -0
- package/dist/storage-content-api/index.js +37 -0
- package/dist/storage-content-api/staticHandler.d.ts +9 -0
- package/dist/storage-content-api/staticHandler.js +61 -0
- package/dist/storage-content-api/types.d.ts +9 -0
- package/dist/storage-content-api/types.js +1 -0
- package/dist/storage-content-api/utilities/getSafeFilename.d.ts +11 -0
- package/dist/storage-content-api/utilities/getSafeFilename.js +59 -0
- package/dist/storage-content-api/utilities/index.d.ts +2 -0
- package/dist/storage-content-api/utilities/index.js +2 -0
- package/dist/storage-content-api/utilities/parseUploadReference.d.ts +17 -0
- package/dist/storage-content-api/utilities/parseUploadReference.js +27 -0
- package/dist/templates/.env.example +5 -0
- package/dist/templates/README.md +19 -0
- package/dist/types/config.d.ts +2 -2
- package/dist/types/config.js +0 -4
- package/dist/types.d.ts +10 -2
- package/dist/types.js +0 -2
- package/dist/utils/adapters/nextjs.d.ts +8 -0
- package/dist/utils/adapters/nextjs.js +61 -0
- package/dist/utils/adapters/nitro.d.ts +8 -0
- package/dist/utils/adapters/nitro.js +172 -0
- package/dist/utils/adapters/vite.d.ts +9 -0
- package/dist/utils/adapters/vite.js +31 -0
- package/dist/utils/asset-collection.d.ts +27 -7
- package/dist/utils/asset-collection.js +59 -32
- package/dist/utils/build-detection.d.ts +5 -12
- package/dist/utils/build-detection.js +74 -13
- package/dist/utils/build-lambda-zip.d.ts +25 -0
- package/dist/utils/build-lambda-zip.js +90 -0
- package/dist/utils/cache-bootstrap.d.ts +7 -0
- package/dist/utils/cache-bootstrap.js +16 -0
- package/dist/utils/config.d.ts +0 -1
- package/dist/utils/config.js +1 -3
- package/dist/utils/deploy-adapter.d.ts +45 -0
- package/dist/utils/deploy-adapter.js +56 -0
- package/dist/utils/download-template.d.ts +9 -2
- package/dist/utils/download-template.js +24 -20
- package/dist/utils/env-management.d.ts +24 -8
- package/dist/utils/env-management.js +119 -66
- package/dist/utils/format-env-suffix.d.ts +11 -0
- package/dist/utils/format-env-suffix.js +11 -0
- package/dist/utils/format.d.ts +0 -1
- package/dist/utils/format.js +0 -2
- package/dist/utils/formatter.d.ts +0 -1
- package/dist/utils/formatter.js +23 -13
- package/dist/utils/fs-utils.d.ts +12 -0
- package/dist/utils/fs-utils.js +55 -0
- package/dist/utils/git.d.ts +0 -1
- package/dist/utils/git.js +0 -2
- package/dist/utils/handle-upgrade.d.ts +8 -0
- package/dist/utils/handle-upgrade.js +39 -0
- package/dist/utils/is-debug.d.ts +0 -1
- package/dist/utils/is-debug.js +0 -2
- package/dist/utils/lambda-config.d.ts +3 -2
- package/dist/utils/lambda-config.js +75 -80
- package/dist/utils/load-payload-config.d.ts +9 -0
- package/dist/utils/load-payload-config.js +27 -0
- package/dist/utils/log.d.ts +0 -1
- package/dist/utils/log.js +0 -2
- package/dist/utils/messages.d.ts +1 -3
- package/dist/utils/messages.js +47 -13
- package/dist/utils/package-manager.d.ts +24 -1
- package/dist/utils/package-manager.js +53 -2
- package/dist/utils/parse-template-spec.d.ts +11 -0
- package/dist/utils/parse-template-spec.js +60 -0
- package/dist/utils/payload-config-ast.d.ts +27 -7
- package/dist/utils/payload-config-ast.js +106 -60
- package/dist/utils/payload-config-finder.d.ts +2 -3
- package/dist/utils/payload-config-finder.js +48 -11
- package/dist/utils/payload-config-modifier.d.ts +1 -2
- package/dist/utils/payload-config-modifier.js +114 -68
- package/dist/utils/payload-package-check.d.ts +28 -3
- package/dist/utils/payload-package-check.js +90 -31
- package/dist/utils/project.d.ts +8 -4
- package/dist/utils/project.js +63 -37
- package/dist/utils/resolve-environment.d.ts +13 -0
- package/dist/utils/resolve-environment.js +29 -0
- package/dist/utils/s3-upload.d.ts +7 -3
- package/dist/utils/s3-upload.js +44 -9
- package/dist/utils/token-display.d.ts +5 -2
- package/dist/utils/token-display.js +49 -24
- package/dist/utils/typescript-validator.d.ts +0 -1
- package/dist/utils/typescript-validator.js +4 -8
- package/dist/utils/version-check.d.ts +2 -0
- package/dist/utils/version-check.js +43 -0
- package/package.json +47 -16
- 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,14 +1,13 @@
|
|
|
1
1
|
import * as jose from 'jose';
|
|
2
2
|
import { APIError, parseCookies } from 'payload';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { JWTValidationError, validatePayloadAdminToken } 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;
|
|
@@ -47,26 +45,28 @@ export class Strategy {
|
|
|
47
45
|
let oauthToken = cookies.get(this.cookieName);
|
|
48
46
|
const refreshToken = cookies.get(`${this.cookieName}-refresh`);
|
|
49
47
|
debugLogger.info({
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
hasOauthToken: !!oauthToken,
|
|
49
|
+
hasRefreshToken: !!refreshToken,
|
|
50
|
+
msg: 'Retrieved tokens from cookies'
|
|
53
51
|
});
|
|
54
52
|
if (!this.collectionOptions.disableJWTFromHeader) {
|
|
55
53
|
// Parse Authorization header if exists
|
|
56
54
|
const jwtFromHeader = headers.get('authorization');
|
|
57
55
|
if (typeof jwtFromHeader === 'string' && jwtFromHeader.startsWith('Bearer ')) {
|
|
58
56
|
debugLogger.info({
|
|
59
|
-
jwtFromHeader,
|
|
60
57
|
msg: 'Found bearer token in authorization header'
|
|
61
58
|
});
|
|
62
59
|
oauthToken = jwtFromHeader.replace('Bearer ', '');
|
|
63
60
|
}
|
|
64
61
|
}
|
|
65
62
|
if (!oauthToken) {
|
|
66
|
-
|
|
63
|
+
// Attempt refresh even when canSetHeaders=false (e.g., during RSC navigation).
|
|
64
|
+
// This allows authentication to succeed for the current request even when
|
|
65
|
+
// cookies cannot be updated. The cookie will be refreshed on the next
|
|
66
|
+
// full page load when canSetHeaders=true.
|
|
67
|
+
if (refreshToken) {
|
|
67
68
|
debugLogger.info({
|
|
68
|
-
msg: 'No access token found, but refresh token exists. Attempting to refresh...'
|
|
69
|
-
refreshToken
|
|
69
|
+
msg: 'No access token found, but refresh token exists. Attempting to refresh...'
|
|
70
70
|
});
|
|
71
71
|
const refreshed = await refreshTokens({
|
|
72
72
|
payload,
|
|
@@ -83,25 +83,31 @@ export class Strategy {
|
|
|
83
83
|
msg: 'Token refreshed. Verifying...',
|
|
84
84
|
verifyResult
|
|
85
85
|
});
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
// Only return response headers (to set cookies) when canSetHeaders is true.
|
|
87
|
+
// During RSC navigation, canSetHeaders=false because response streaming
|
|
88
|
+
// has already started and cookies cannot be modified.
|
|
89
|
+
if (canSetHeaders) {
|
|
90
|
+
if (verifyResult.responseHeaders) {
|
|
91
|
+
mergeHeaders(verifyResult.responseHeaders, refreshed.headers);
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
responseHeaders: refreshed.headers,
|
|
95
|
+
user: verifyResult.user
|
|
96
|
+
};
|
|
88
97
|
}
|
|
98
|
+
// Authenticate this request without updating cookies
|
|
89
99
|
return {
|
|
90
|
-
responseHeaders: refreshed.headers,
|
|
91
100
|
user: verifyResult.user
|
|
92
101
|
};
|
|
93
102
|
} else {
|
|
94
103
|
debugLogger.info({
|
|
95
|
-
msg: 'Token refresh failed'
|
|
96
|
-
refreshed,
|
|
97
|
-
refreshToken
|
|
104
|
+
msg: 'Token refresh failed'
|
|
98
105
|
});
|
|
99
106
|
}
|
|
100
|
-
} else {
|
|
101
|
-
return {
|
|
102
|
-
user: null
|
|
103
|
-
};
|
|
104
107
|
}
|
|
108
|
+
return {
|
|
109
|
+
user: null
|
|
110
|
+
};
|
|
105
111
|
}
|
|
106
112
|
let oauthTokenVerifyResult = null;
|
|
107
113
|
// First, try to verify token
|
|
@@ -136,16 +142,17 @@ export class Strategy {
|
|
|
136
142
|
});
|
|
137
143
|
}
|
|
138
144
|
}
|
|
139
|
-
|
|
145
|
+
// Handle expired access token with valid refresh token.
|
|
146
|
+
// Same pattern as above: refresh regardless of canSetHeaders to support RSC navigation,
|
|
147
|
+
// but only update cookies when canSetHeaders=true.
|
|
148
|
+
if (oauthTokenVerifyResult instanceof JWTValidationError && oauthTokenVerifyResult.code === 'EXPIRED' && refreshToken && !this.collectionOptions.usePayloadJWT) {
|
|
140
149
|
const refreshed = await refreshTokens({
|
|
141
150
|
payload,
|
|
142
151
|
refreshToken,
|
|
143
152
|
strategy: this
|
|
144
153
|
});
|
|
145
154
|
debugLogger.info({
|
|
146
|
-
msg: 'Token expired. Refreshing...'
|
|
147
|
-
refreshed,
|
|
148
|
-
refreshToken
|
|
155
|
+
msg: 'Token expired. Refreshing...'
|
|
149
156
|
});
|
|
150
157
|
if (refreshed) {
|
|
151
158
|
const verifyResult = await this.verify({
|
|
@@ -157,18 +164,22 @@ export class Strategy {
|
|
|
157
164
|
msg: 'Token refreshed. Verifying...',
|
|
158
165
|
verifyResult
|
|
159
166
|
});
|
|
160
|
-
if (
|
|
161
|
-
|
|
167
|
+
if (canSetHeaders) {
|
|
168
|
+
if (verifyResult.responseHeaders) {
|
|
169
|
+
mergeHeaders(verifyResult.responseHeaders, refreshed.headers);
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
responseHeaders: refreshed.headers,
|
|
173
|
+
user: verifyResult.user
|
|
174
|
+
};
|
|
162
175
|
}
|
|
176
|
+
// Authenticate this request without updating cookies
|
|
163
177
|
return {
|
|
164
|
-
responseHeaders: refreshed.headers,
|
|
165
178
|
user: verifyResult.user
|
|
166
179
|
};
|
|
167
180
|
} else {
|
|
168
181
|
debugLogger.info({
|
|
169
|
-
msg: 'Token refresh failed'
|
|
170
|
-
refreshed,
|
|
171
|
-
refreshToken
|
|
182
|
+
msg: 'Token refresh failed'
|
|
172
183
|
});
|
|
173
184
|
}
|
|
174
185
|
}
|
|
@@ -200,6 +211,10 @@ export class Strategy {
|
|
|
200
211
|
for(let attempt = 1; attempt <= 5; attempt++){
|
|
201
212
|
try {
|
|
202
213
|
this.meta = await fetch(this.identityMetadataURL).then((res)=>res.json());
|
|
214
|
+
if (this.meta) {
|
|
215
|
+
// TODO: This is a hack to get the DefaultLoginButton to work with dynamic OAuth client registration
|
|
216
|
+
this.meta.authorization_endpoint = this.meta?.authorization_endpoint + '/cms';
|
|
217
|
+
}
|
|
203
218
|
this.debugLog(`fetchMeta - success on attempt ${attempt}`);
|
|
204
219
|
if (this.meta?.jwks_uri) {
|
|
205
220
|
this.jwks = await fetch(this.meta.jwks_uri).then((res)=>res.json());
|
|
@@ -259,7 +274,15 @@ export class Strategy {
|
|
|
259
274
|
}
|
|
260
275
|
async jwtVerify({ payload, token }) {
|
|
261
276
|
try {
|
|
262
|
-
const
|
|
277
|
+
const audience = payload.config.custom.figma.environmentId;
|
|
278
|
+
if (!audience) {
|
|
279
|
+
throw new Error('Cannot validate token audience: environmentId is not configured');
|
|
280
|
+
}
|
|
281
|
+
const verified = await validatePayloadAdminToken({
|
|
282
|
+
audience,
|
|
283
|
+
environment: getInfraEnvironment(),
|
|
284
|
+
token
|
|
285
|
+
});
|
|
263
286
|
if (typeof verified !== 'string') {
|
|
264
287
|
return verified;
|
|
265
288
|
}
|
|
@@ -276,5 +299,3 @@ export class Strategy {
|
|
|
276
299
|
return null;
|
|
277
300
|
}
|
|
278
301
|
}
|
|
279
|
-
|
|
280
|
-
//# sourceMappingURL=index.js.map
|
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
|
*/
|
|
@@ -189,4 +206,3 @@ export type DebugLogger = {
|
|
|
189
206
|
error: LogFn;
|
|
190
207
|
info: LogFn;
|
|
191
208
|
};
|
|
192
|
-
//# sourceMappingURL=types.d.ts.map
|
package/dist/oauth/types.js
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { SanitizedConfig } from 'payload';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves the admin panel's "unauthorized" view path for a given Payload
|
|
4
|
+
* config, honoring tenant-customized admin (`config.routes.admin`, default
|
|
5
|
+
* `/admin`) and unauthorized (`config.admin.routes.unauthorized`, default
|
|
6
|
+
* `/unauthorized`) route slugs, plus any Next.js `basePath`.
|
|
7
|
+
*
|
|
8
|
+
* @example '/admin/unauthorized' (defaults) — '/docs/cms/no-access' (basePath + customized)
|
|
9
|
+
*/
|
|
10
|
+
export declare function getUnauthorizedPath(config: SanitizedConfig): string;
|
|
11
|
+
/**
|
|
12
|
+
* Builds a 302 redirect to the admin panel's "unauthorized" view.
|
|
13
|
+
*/
|
|
14
|
+
export declare function buildUnauthorizedRedirect(config: SanitizedConfig): Response;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { formatAdminURL } from 'payload/shared';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves the admin panel's "unauthorized" view path for a given Payload
|
|
4
|
+
* config, honoring tenant-customized admin (`config.routes.admin`, default
|
|
5
|
+
* `/admin`) and unauthorized (`config.admin.routes.unauthorized`, default
|
|
6
|
+
* `/unauthorized`) route slugs, plus any Next.js `basePath`.
|
|
7
|
+
*
|
|
8
|
+
* @example '/admin/unauthorized' (defaults) — '/docs/cms/no-access' (basePath + customized)
|
|
9
|
+
*/ export function getUnauthorizedPath(config) {
|
|
10
|
+
const adminRoute = config.routes?.admin || '/admin';
|
|
11
|
+
const unauthorizedRoute = config.admin?.routes?.unauthorized || '/unauthorized';
|
|
12
|
+
return formatAdminURL({
|
|
13
|
+
adminRoute,
|
|
14
|
+
includeBasePath: true,
|
|
15
|
+
path: unauthorizedRoute,
|
|
16
|
+
relative: true
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Builds a 302 redirect to the admin panel's "unauthorized" view.
|
|
21
|
+
*/ export function buildUnauthorizedRedirect(config) {
|
|
22
|
+
return new Response(null, {
|
|
23
|
+
headers: {
|
|
24
|
+
Location: getUnauthorizedPath(config)
|
|
25
|
+
},
|
|
26
|
+
status: 302
|
|
27
|
+
});
|
|
28
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { generateCookie } from 'payload';
|
|
2
2
|
import { getCookieExpiration } from './getCookieExpiration.js';
|
|
3
|
+
import { withPartitionedCookie } from './withPartitionedCookie.js';
|
|
3
4
|
export const clearCookie = (args)=>{
|
|
4
5
|
const options = {
|
|
5
6
|
...args.cookieOptions,
|
|
@@ -15,7 +16,8 @@ export const clearCookie = (args)=>{
|
|
|
15
16
|
if (!args.req.responseHeaders) {
|
|
16
17
|
args.req.responseHeaders = new Headers();
|
|
17
18
|
}
|
|
18
|
-
|
|
19
|
+
// Match the Partitioned attribute the cookie was set with — a Max-Age=0 clear
|
|
20
|
+
// without it targets the unpartitioned jar and won't delete the partitioned
|
|
21
|
+
// cookie, so logout wouldn't clear the session in the cross-site Make iframe.
|
|
22
|
+
args.req.responseHeaders.append('Set-Cookie', withPartitionedCookie(clearedCookie));
|
|
19
23
|
};
|
|
20
|
-
|
|
21
|
-
//# sourceMappingURL=clearCookie.js.map
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
export const createCookieOptions = ({ collection, headers, pluginOptions })=>{
|
|
2
|
+
// Default to SameSite=None + Secure (and `Partitioned`, appended in
|
|
3
|
+
// establishSession via withPartitionedCookie) so the session cookies survive
|
|
4
|
+
// the cross-site Make-preview iframe — the admin panel runs on a different
|
|
5
|
+
// site from the top-level figma.com page, and a Lax/unmarked cookie is not
|
|
6
|
+
// sent back, looping the login. Mirrors the CSRF cookie (buildCsrfCookieHeader).
|
|
7
|
+
// Self-hosters on a same-site setup can override via collection.auth.cookies
|
|
8
|
+
// or pluginOptions.createCookieOptions below.
|
|
2
9
|
let cookieOptions = {
|
|
3
10
|
domain: undefined,
|
|
4
11
|
httpOnly: true,
|
|
5
12
|
path: '/',
|
|
6
|
-
sameSite:
|
|
7
|
-
secure:
|
|
13
|
+
sameSite: 'None',
|
|
14
|
+
secure: true
|
|
8
15
|
};
|
|
9
16
|
if (typeof collection.auth === 'object' && typeof collection.auth.cookies === 'object') {
|
|
10
17
|
const { domain, sameSite, secure } = collection.auth.cookies;
|
|
@@ -38,5 +45,3 @@ export const createCookieOptions = ({ collection, headers, pluginOptions })=>{
|
|
|
38
45
|
}
|
|
39
46
|
return cookieOptions;
|
|
40
47
|
};
|
|
41
|
-
|
|
42
|
-
//# sourceMappingURL=createCookieOptions.js.map
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
debugLogger: DebugLogger;
|
|
9
|
+
environmentId: string;
|
|
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
|
+
* Payload Admin token, and write the main + refresh + user-info cookies to
|
|
19
|
+
* `req.responseHeaders`. Throws `APIError` if the Admin token mint fails.
|
|
20
|
+
*/
|
|
21
|
+
export declare const establishSession: ({ accessToken, collection, collectionOptions, debugLogger, environmentId, pluginOptions, refreshTokenExpiresIn, req, strategy, }: Args) => Promise<void>;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { APIError, generateCookie } from 'payload';
|
|
2
|
+
import { getPayloadAdminToken, getUserInfo } from '../../api/figma-api.js';
|
|
3
|
+
import { createCookieOptions } from './createCookieOptions.js';
|
|
4
|
+
import { getCookieExpiration } from './getCookieExpiration.js';
|
|
5
|
+
import { withPartitionedCookie } from './withPartitionedCookie.js';
|
|
6
|
+
/**
|
|
7
|
+
* Given a valid OAuth access_token: fetch user info (non-fatal), mint a
|
|
8
|
+
* Payload Admin token, and write the main + refresh + user-info cookies to
|
|
9
|
+
* `req.responseHeaders`. Throws `APIError` if the Admin token mint fails.
|
|
10
|
+
*/ export const establishSession = async ({ accessToken, collection, collectionOptions, debugLogger, environmentId, pluginOptions, refreshTokenExpiresIn, req, strategy })=>{
|
|
11
|
+
const oauthCredential = {
|
|
12
|
+
type: 'oauth',
|
|
13
|
+
token: accessToken
|
|
14
|
+
};
|
|
15
|
+
// Non-fatal: user just won't have handle/image on first request.
|
|
16
|
+
let figmaUserInfo = null;
|
|
17
|
+
try {
|
|
18
|
+
figmaUserInfo = await getUserInfo(oauthCredential);
|
|
19
|
+
debugLogger.info({
|
|
20
|
+
msg: 'Fetched Figma user info'
|
|
21
|
+
});
|
|
22
|
+
} catch (err) {
|
|
23
|
+
debugLogger.error({
|
|
24
|
+
err,
|
|
25
|
+
msg: 'Failed to fetch Figma user info'
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
const adminToken = await getPayloadAdminToken(oauthCredential, environmentId);
|
|
29
|
+
if (!adminToken.token) {
|
|
30
|
+
const errMsg = 'No Payload Admin token returned from Figma API';
|
|
31
|
+
req.payload.logger.error({
|
|
32
|
+
msg: errMsg
|
|
33
|
+
});
|
|
34
|
+
throw new APIError(errMsg);
|
|
35
|
+
}
|
|
36
|
+
const cookieOptions = createCookieOptions({
|
|
37
|
+
collection,
|
|
38
|
+
headers: req.headers,
|
|
39
|
+
pluginOptions
|
|
40
|
+
});
|
|
41
|
+
if (!req.responseHeaders) {
|
|
42
|
+
req.responseHeaders = new Headers();
|
|
43
|
+
}
|
|
44
|
+
// The -refresh cookie holds the OAuth access_token so refreshTokens can
|
|
45
|
+
// re-mint project_tokens from it on JWT expiry.
|
|
46
|
+
if (!collectionOptions.usePayloadJWT) {
|
|
47
|
+
const refreshCookie = generateCookie({
|
|
48
|
+
...cookieOptions,
|
|
49
|
+
name: `${strategy.cookieName}-refresh`,
|
|
50
|
+
expires: getCookieExpiration(cookieOptions?.expires ?? refreshTokenExpiresIn ?? 31_556_952),
|
|
51
|
+
returnCookieAsObject: false,
|
|
52
|
+
value: accessToken
|
|
53
|
+
});
|
|
54
|
+
req.responseHeaders.append('Set-Cookie', withPartitionedCookie(refreshCookie));
|
|
55
|
+
}
|
|
56
|
+
const tokenExpires = cookieOptions?.expires ? getCookieExpiration(cookieOptions.expires) : new Date(adminToken.expiresAt);
|
|
57
|
+
const tokenCookie = generateCookie({
|
|
58
|
+
...cookieOptions,
|
|
59
|
+
name: strategy.cookieName,
|
|
60
|
+
expires: tokenExpires,
|
|
61
|
+
returnCookieAsObject: false,
|
|
62
|
+
value: adminToken.token
|
|
63
|
+
});
|
|
64
|
+
req.responseHeaders.append('Set-Cookie', withPartitionedCookie(tokenCookie));
|
|
65
|
+
// Short-lived handoff cookie consumed by defaultVerify on the next request.
|
|
66
|
+
if (figmaUserInfo) {
|
|
67
|
+
const userInfoValue = Buffer.from(JSON.stringify({
|
|
68
|
+
handle: figmaUserInfo.handle,
|
|
69
|
+
img_url: figmaUserInfo.img_url
|
|
70
|
+
})).toString('base64');
|
|
71
|
+
const userInfoCookie = generateCookie({
|
|
72
|
+
...cookieOptions,
|
|
73
|
+
name: pluginOptions?.userInfoCookieName ?? 'figma-user-info',
|
|
74
|
+
expires: new Date(Date.now() + 60_000),
|
|
75
|
+
returnCookieAsObject: false,
|
|
76
|
+
value: userInfoValue
|
|
77
|
+
});
|
|
78
|
+
req.responseHeaders.append('Set-Cookie', withPartitionedCookie(userInfoCookie));
|
|
79
|
+
}
|
|
80
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Strategy } from '../strategy/index.js';
|
|
2
|
+
interface Args {
|
|
3
|
+
/** Authorization code received from the IdP redirect. */
|
|
4
|
+
code: string;
|
|
5
|
+
/** PKCE verifier; omit for non-PKCE flows. */
|
|
6
|
+
codeVerifier?: string;
|
|
7
|
+
/** Must match the redirect_uri the authorization request used. */
|
|
8
|
+
redirectUri: string;
|
|
9
|
+
strategy: Strategy;
|
|
10
|
+
}
|
|
11
|
+
export interface TokenEndpointResponse {
|
|
12
|
+
access_token?: null | string;
|
|
13
|
+
error?: string;
|
|
14
|
+
error_description?: string;
|
|
15
|
+
expires_in?: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* POSTs an authorization code to the IdP's `token_endpoint` and returns the
|
|
19
|
+
* raw response body. Callers handle error/missing-token logging in their own
|
|
20
|
+
* style — this helper only owns the request shape.
|
|
21
|
+
*/
|
|
22
|
+
export declare const exchangeCodeForAccessToken: ({ code, codeVerifier, redirectUri, strategy, }: Args) => Promise<TokenEndpointResponse>;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* POSTs an authorization code to the IdP's `token_endpoint` and returns the
|
|
3
|
+
* raw response body. Callers handle error/missing-token logging in their own
|
|
4
|
+
* style — this helper only owns the request shape.
|
|
5
|
+
*/ export const exchangeCodeForAccessToken = async ({ code, codeVerifier, redirectUri, strategy })=>{
|
|
6
|
+
const body = {
|
|
7
|
+
client_id: strategy.clientID,
|
|
8
|
+
code,
|
|
9
|
+
grant_type: 'authorization_code',
|
|
10
|
+
redirect_uri: redirectUri
|
|
11
|
+
};
|
|
12
|
+
if (codeVerifier) {
|
|
13
|
+
body.code_verifier = codeVerifier;
|
|
14
|
+
}
|
|
15
|
+
if (strategy.collectionOptions.clientSecret) {
|
|
16
|
+
body.client_secret = strategy.collectionOptions.clientSecret;
|
|
17
|
+
}
|
|
18
|
+
const res = await fetch(strategy.meta.token_endpoint, {
|
|
19
|
+
body: new URLSearchParams(body),
|
|
20
|
+
headers: {
|
|
21
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
22
|
+
},
|
|
23
|
+
method: 'POST'
|
|
24
|
+
});
|
|
25
|
+
return await res.json();
|
|
26
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Copied from share/figma-url/src/hostnames.ts.
|
|
2
|
+
// This package is published to npm (@payloadcms/figma) and cannot import from
|
|
3
|
+
// the monorepo's internal share/ tree, so the list is duplicated here.
|
|
4
|
+
export const FIGMA_HOSTNAMES = new Set([
|
|
5
|
+
'embed.figma.com',
|
|
6
|
+
'embed.figma-gov.com',
|
|
7
|
+
'embed.local.figma.engineering',
|
|
8
|
+
'embed.staging.figma.com',
|
|
9
|
+
'figma.com',
|
|
10
|
+
'figma-gov.com',
|
|
11
|
+
'local.figma.engineering',
|
|
12
|
+
'localhost',
|
|
13
|
+
'staging.figma.com',
|
|
14
|
+
'www.figma.com',
|
|
15
|
+
'www.figma-gov.com'
|
|
16
|
+
]);
|
|
17
|
+
export const isFigmaOrigin = (origin)=>{
|
|
18
|
+
try {
|
|
19
|
+
const { hostname } = new URL(origin);
|
|
20
|
+
return FIGMA_HOSTNAMES.has(hostname) || hostname.endsWith('.figdev.systems');
|
|
21
|
+
} catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
@@ -5,6 +5,16 @@ interface Args {
|
|
|
5
5
|
collection: CollectionConfig;
|
|
6
6
|
collectionOptions: CollectionOptions;
|
|
7
7
|
endpointSlug: string;
|
|
8
|
+
/**
|
|
9
|
+
* If the request already has an `__Host-payload-oauth-state_csrf` cookie,
|
|
10
|
+
* pass its value here — `getAuthorizeURL` will reuse it as `state.csrf`
|
|
11
|
+
* instead of minting a fresh nonce. This is what makes `/meta`
|
|
12
|
+
* idempotent across multiple calls in a single browser session (React
|
|
13
|
+
* Strict Mode re-mounts, retry-after-failure, multiple tabs) and
|
|
14
|
+
* prevents the cookie/state mismatch race where one call overwrites
|
|
15
|
+
* another call's cookie.
|
|
16
|
+
*/
|
|
17
|
+
existingCsrfNonce?: null | string;
|
|
8
18
|
failedRedirect?: unknown;
|
|
9
19
|
payload: Payload;
|
|
10
20
|
pluginOptions: PluginOptions;
|
|
@@ -12,6 +22,59 @@ interface Args {
|
|
|
12
22
|
serverURLOverride?: unknown;
|
|
13
23
|
strategy: Strategy;
|
|
14
24
|
}
|
|
15
|
-
export
|
|
25
|
+
export interface AuthorizeURLParams {
|
|
26
|
+
[key: string]: string;
|
|
27
|
+
client_id: string;
|
|
28
|
+
code_challenge: string;
|
|
29
|
+
code_challenge_method: string;
|
|
30
|
+
nonce: string;
|
|
31
|
+
redirect_uri: string;
|
|
32
|
+
response_mode: string;
|
|
33
|
+
response_type: string;
|
|
34
|
+
scope: string;
|
|
35
|
+
state: string;
|
|
36
|
+
}
|
|
37
|
+
export interface AuthorizeURLResult {
|
|
38
|
+
authorizeURL: string;
|
|
39
|
+
/**
|
|
40
|
+
* The plaintext CSRF nonce that the caller MUST set as an HttpOnly
|
|
41
|
+
* cookie on the response (see `OAUTH_STATE_CSRF_COOKIE_NAME`). `/sso/login`
|
|
42
|
+
* compares this value to the cookie on callback — this is the
|
|
43
|
+
* browser-binding required by RFC 6749 §10.12.
|
|
44
|
+
*/
|
|
45
|
+
csrfNonce: string;
|
|
46
|
+
params: AuthorizeURLParams;
|
|
47
|
+
}
|
|
48
|
+
export declare const getAuthorizeURL: ({ collection, collectionOptions, endpointSlug, existingCsrfNonce, failedRedirect, payload, pluginOptions, redirect, serverURLOverride, strategy, }: Args) => Promise<AuthorizeURLResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Name of the HttpOnly cookie that carries the browser-bound CSRF nonce
|
|
51
|
+
* for the OAuth flow. The `__Host-` prefix instructs browsers to enforce:
|
|
52
|
+
* Secure, no Domain attribute (host-only), and Path=/ — which together
|
|
53
|
+
* prevent sibling subdomains from setting or overwriting it.
|
|
54
|
+
*/
|
|
55
|
+
export declare const OAUTH_STATE_CSRF_COOKIE_NAME = "__Host-payload-oauth-state_csrf";
|
|
56
|
+
/**
|
|
57
|
+
* Build the `Set-Cookie` header value for the CSRF cookie. SameSite=None
|
|
58
|
+
* + Secure so the cookie survives the IdP cross-site redirect back into
|
|
59
|
+
* /sso/login, AND so the iframe auto-login path works (the iframe is a
|
|
60
|
+
* third-party context from the top-level Figma page). Path=/ is required
|
|
61
|
+
* by the `__Host-` prefix.
|
|
62
|
+
*
|
|
63
|
+
* `Partitioned` (CHIPS) is required because the Make preview embeds the
|
|
64
|
+
* admin panel in a cross-site iframe. Under Chrome's third-party-cookie
|
|
65
|
+
* restrictions a `SameSite=None` cookie set in a third-party context is
|
|
66
|
+
* NOT sent back unless it is partitioned by the top-level site. Without it
|
|
67
|
+
* the `__Host-payload-oauth-state_csrf` cookie is dropped on the way back
|
|
68
|
+
* to /sso/login, the cookie↔state.csrf binding check fails, and login dies
|
|
69
|
+
* with "CSRF cookie mismatch" (intermittent sign-in loop). `__Host-` and
|
|
70
|
+
* `Partitioned` are mutually compatible.
|
|
71
|
+
*/
|
|
72
|
+
export declare const buildCsrfCookieHeader: (nonce: string) => string;
|
|
73
|
+
/**
|
|
74
|
+
* `Set-Cookie` header to clear the CSRF cookie after a successful (or
|
|
75
|
+
* failed) callback. Same attributes as the set version, plus Max-Age=0.
|
|
76
|
+
* Must include `Partitioned` so the clear targets the same partitioned
|
|
77
|
+
* cookie jar the set wrote to (an unpartitioned clear would not match).
|
|
78
|
+
*/
|
|
79
|
+
export declare const buildCsrfCookieClearHeader: () => string;
|
|
16
80
|
export {};
|
|
17
|
-
//# sourceMappingURL=getAuthorizeURL.d.ts.map
|