directus 9.23.1 → 9.23.4
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/app.js +25 -21
- package/dist/auth/auth.d.ts +3 -3
- package/dist/auth/auth.js +2 -0
- package/dist/auth/drivers/ldap.d.ts +1 -1
- package/dist/auth/drivers/ldap.js +57 -46
- package/dist/auth/drivers/local.d.ts +1 -1
- package/dist/auth/drivers/local.js +20 -17
- package/dist/auth/drivers/oauth2.d.ts +1 -1
- package/dist/auth/drivers/oauth2.js +44 -35
- package/dist/auth/drivers/openid.d.ts +1 -1
- package/dist/auth/drivers/openid.js +50 -41
- package/dist/auth/drivers/saml.d.ts +1 -1
- package/dist/auth/drivers/saml.js +20 -17
- package/dist/auth.d.ts +1 -1
- package/dist/auth.js +8 -7
- package/dist/cache.d.ts +9 -1
- package/dist/cache.js +66 -18
- package/dist/cli/commands/bootstrap/index.js +7 -6
- package/dist/cli/commands/init/index.js +3 -3
- package/dist/cli/commands/schema/apply.js +14 -15
- package/dist/cli/commands/schema/snapshot.js +2 -2
- package/dist/cli/utils/create-db-connection.d.ts +1 -1
- package/dist/cli/utils/create-db-connection.js +3 -2
- package/dist/cli/utils/create-env/index.d.ts +2 -2
- package/dist/cli/utils/create-env/index.js +1 -1
- package/dist/cli/utils/drivers.d.ts +1 -1
- package/dist/constants.d.ts +3 -2
- package/dist/constants.js +7 -7
- package/dist/controllers/activity.js +10 -11
- package/dist/controllers/assets.js +31 -25
- package/dist/controllers/auth.js +40 -26
- package/dist/controllers/collections.js +10 -10
- package/dist/controllers/dashboards.js +14 -11
- package/dist/controllers/extensions.js +3 -3
- package/dist/controllers/fields.js +20 -20
- package/dist/controllers/files.js +26 -20
- package/dist/controllers/flows.js +16 -13
- package/dist/controllers/folders.js +14 -11
- package/dist/controllers/graphql.js +6 -8
- package/dist/controllers/items.js +22 -19
- package/dist/controllers/not-found.d.ts +1 -1
- package/dist/controllers/not-found.js +1 -2
- package/dist/controllers/notifications.js +14 -11
- package/dist/controllers/operations.js +14 -11
- package/dist/controllers/panels.js +14 -11
- package/dist/controllers/permissions.js +14 -11
- package/dist/controllers/presets.js +14 -11
- package/dist/controllers/relations.js +10 -10
- package/dist/controllers/revisions.js +3 -3
- package/dist/controllers/roles.js +14 -11
- package/dist/controllers/schema.js +5 -5
- package/dist/controllers/server.js +7 -7
- package/dist/controllers/settings.js +2 -2
- package/dist/controllers/shares.js +21 -18
- package/dist/controllers/users.js +32 -36
- package/dist/controllers/utils.js +10 -15
- package/dist/controllers/webhooks.js +14 -11
- package/dist/database/helpers/fn/dialects/mssql.d.ts +1 -1
- package/dist/database/helpers/fn/dialects/mssql.js +10 -11
- package/dist/database/helpers/fn/dialects/mysql.d.ts +1 -1
- package/dist/database/helpers/fn/dialects/mysql.js +2 -3
- package/dist/database/helpers/fn/dialects/oracle.d.ts +1 -1
- package/dist/database/helpers/fn/dialects/oracle.js +10 -11
- package/dist/database/helpers/fn/dialects/postgres.d.ts +1 -1
- package/dist/database/helpers/fn/dialects/postgres.js +10 -11
- package/dist/database/helpers/fn/dialects/sqlite.d.ts +1 -1
- package/dist/database/helpers/fn/dialects/sqlite.js +10 -11
- package/dist/database/helpers/fn/types.d.ts +5 -6
- package/dist/database/helpers/fn/types.js +4 -5
- package/dist/database/helpers/geometry/dialects/mssql.d.ts +3 -3
- package/dist/database/helpers/geometry/dialects/mysql.d.ts +1 -1
- package/dist/database/helpers/geometry/dialects/oracle.d.ts +3 -3
- package/dist/database/helpers/geometry/dialects/postgres.d.ts +3 -3
- package/dist/database/helpers/geometry/dialects/postgres.js +1 -2
- package/dist/database/helpers/geometry/dialects/redshift.d.ts +2 -2
- package/dist/database/helpers/geometry/dialects/sqlite.d.ts +1 -1
- package/dist/database/helpers/geometry/types.d.ts +2 -2
- package/dist/database/helpers/geometry/types.js +1 -2
- package/dist/database/helpers/index.d.ts +5 -5
- package/dist/database/helpers/schema/dialects/cockroachdb.d.ts +1 -1
- package/dist/database/helpers/schema/dialects/mssql.d.ts +1 -1
- package/dist/database/helpers/schema/dialects/mysql.d.ts +1 -1
- package/dist/database/helpers/schema/dialects/mysql.js +1 -2
- package/dist/database/helpers/schema/dialects/oracle.d.ts +2 -2
- package/dist/database/helpers/schema/dialects/oracle.js +4 -6
- package/dist/database/helpers/schema/types.d.ts +4 -4
- package/dist/database/helpers/types.d.ts +1 -1
- package/dist/database/helpers/types.js +1 -0
- package/dist/database/index.d.ts +1 -1
- package/dist/database/index.js +13 -13
- package/dist/database/migrations/20201028A-remove-collection-foreign-keys.d.ts +1 -1
- package/dist/database/migrations/20201029A-remove-system-relations.d.ts +1 -1
- package/dist/database/migrations/20201029B-remove-system-collections.d.ts +1 -1
- package/dist/database/migrations/20201029C-remove-system-fields.d.ts +1 -1
- package/dist/database/migrations/20201105A-add-cascade-system-relations.d.ts +1 -1
- package/dist/database/migrations/20201105B-change-webhook-url-type.d.ts +1 -1
- package/dist/database/migrations/20210225A-add-relations-sort-field.d.ts +1 -1
- package/dist/database/migrations/20210225A-add-relations-sort-field.js +1 -2
- package/dist/database/migrations/20210304A-remove-locked-fields.d.ts +1 -1
- package/dist/database/migrations/20210312A-webhooks-collections-text.d.ts +1 -1
- package/dist/database/migrations/20210331A-add-refresh-interval.d.ts +1 -1
- package/dist/database/migrations/20210415A-make-filesize-nullable.d.ts +1 -1
- package/dist/database/migrations/20210416A-add-collections-accountability.d.ts +1 -1
- package/dist/database/migrations/20210422A-remove-files-interface.d.ts +1 -1
- package/dist/database/migrations/20210506A-rename-interfaces.d.ts +1 -1
- package/dist/database/migrations/20210510A-restructure-relations.d.ts +1 -1
- package/dist/database/migrations/20210518A-add-foreign-key-constraints.d.ts +1 -1
- package/dist/database/migrations/20210518A-add-foreign-key-constraints.js +1 -1
- package/dist/database/migrations/20210519A-add-system-fk-triggers.d.ts +1 -1
- package/dist/database/migrations/20210519A-add-system-fk-triggers.js +2 -2
- package/dist/database/migrations/20210521A-add-collections-icon-color.d.ts +1 -1
- package/dist/database/migrations/20210525A-add-insights.d.ts +1 -1
- package/dist/database/migrations/20210608A-add-deep-clone-config.d.ts +1 -1
- package/dist/database/migrations/20210626A-change-filesize-bigint.d.ts +1 -1
- package/dist/database/migrations/20210716A-add-conditions-to-fields.d.ts +1 -1
- package/dist/database/migrations/20210721A-add-default-folder.d.ts +1 -1
- package/dist/database/migrations/20210802A-replace-groups.d.ts +1 -1
- package/dist/database/migrations/20210803A-add-required-to-fields.d.ts +1 -1
- package/dist/database/migrations/20210805A-update-groups.d.ts +1 -1
- package/dist/database/migrations/20210805B-change-image-metadata-structure.d.ts +1 -1
- package/dist/database/migrations/20210805B-change-image-metadata-structure.js +15 -15
- package/dist/database/migrations/20210811A-add-geometry-config.d.ts +1 -1
- package/dist/database/migrations/20210831A-remove-limit-column.d.ts +1 -1
- package/dist/database/migrations/20210903A-add-auth-provider.d.ts +1 -1
- package/dist/database/migrations/20210907A-webhooks-collections-not-null.d.ts +1 -1
- package/dist/database/migrations/20210910A-move-module-setup.d.ts +1 -1
- package/dist/database/migrations/20210920A-webhooks-url-not-null.d.ts +1 -1
- package/dist/database/migrations/20210924A-add-collection-organization.d.ts +1 -1
- package/dist/database/migrations/20210927A-replace-fields-group.d.ts +1 -1
- package/dist/database/migrations/20210927B-replace-m2m-interface.d.ts +1 -1
- package/dist/database/migrations/20210929A-rename-login-action.d.ts +1 -1
- package/dist/database/migrations/20211007A-update-presets.d.ts +1 -1
- package/dist/database/migrations/20211007A-update-presets.js +7 -9
- package/dist/database/migrations/20211009A-add-auth-data.d.ts +1 -1
- package/dist/database/migrations/20211016A-add-webhook-headers.d.ts +1 -1
- package/dist/database/migrations/20211103A-set-unique-to-user-token.d.ts +1 -1
- package/dist/database/migrations/20211103B-update-special-geometry.d.ts +1 -1
- package/dist/database/migrations/20211104A-remove-collections-listing.d.ts +1 -1
- package/dist/database/migrations/20211118A-add-notifications.d.ts +1 -1
- package/dist/database/migrations/20211211A-add-shares.d.ts +1 -1
- package/dist/database/migrations/20211230A-add-project-descriptor.d.ts +1 -1
- package/dist/database/migrations/20220303A-remove-default-project-color.d.ts +1 -1
- package/dist/database/migrations/20220308A-add-bookmark-icon-and-color.d.ts +1 -1
- package/dist/database/migrations/20220314A-add-translation-strings.d.ts +1 -1
- package/dist/database/migrations/20220322A-rename-field-typecast-flags.d.ts +1 -1
- package/dist/database/migrations/20220323A-add-field-validation.d.ts +1 -1
- package/dist/database/migrations/20220325A-fix-typecast-flags.d.ts +1 -1
- package/dist/database/migrations/20220325B-add-default-language.d.ts +1 -1
- package/dist/database/migrations/20220402A-remove-default-value-panel-icon.d.ts +1 -1
- package/dist/database/migrations/20220429A-add-flows.d.ts +1 -1
- package/dist/database/migrations/20220429B-add-color-to-insights-icon.d.ts +1 -1
- package/dist/database/migrations/20220429C-drop-non-null-from-ip-of-activity.d.ts +1 -1
- package/dist/database/migrations/20220429D-drop-non-null-from-sender-of-notifications.d.ts +1 -1
- package/dist/database/migrations/20220614A-rename-hook-trigger-to-event.d.ts +1 -1
- package/dist/database/migrations/20220801A-update-notifications-timestamp-column.d.ts +1 -1
- package/dist/database/migrations/20220802A-add-custom-aspect-ratios.d.ts +1 -1
- package/dist/database/migrations/20220826A-add-origin-to-accountability.d.ts +1 -1
- package/dist/database/migrations/run.d.ts +1 -1
- package/dist/database/migrations/run.js +1 -1
- package/dist/database/run-ast.d.ts +3 -3
- package/dist/database/run-ast.js +21 -30
- package/dist/database/seeds/run.d.ts +1 -1
- package/dist/database/seeds/run.js +1 -2
- package/dist/database/system-data/app-access-permissions/index.d.ts +1 -1
- package/dist/database/system-data/collections/index.d.ts +1 -1
- package/dist/database/system-data/collections/index.js +2 -2
- package/dist/database/system-data/fields/collections.yaml +2 -0
- package/dist/database/system-data/fields/index.d.ts +1 -1
- package/dist/database/system-data/fields/index.js +3 -4
- package/dist/database/system-data/fields/settings.yaml +4 -0
- package/dist/database/system-data/relations/index.d.ts +1 -1
- package/dist/emitter.d.ts +1 -1
- package/dist/emitter.js +3 -0
- package/dist/env.js +11 -3
- package/dist/exceptions/database/dialects/mssql.d.ts +1 -1
- package/dist/exceptions/database/dialects/mssql.js +5 -6
- package/dist/exceptions/database/dialects/mysql.d.ts +1 -1
- package/dist/exceptions/database/dialects/mysql.js +19 -25
- package/dist/exceptions/database/dialects/oracle.d.ts +1 -1
- package/dist/exceptions/database/dialects/postgres.d.ts +1 -1
- package/dist/exceptions/database/dialects/sqlite.d.ts +1 -1
- package/dist/exceptions/database/translate.d.ts +1 -1
- package/dist/exceptions/database/value-out-of-range.js +1 -1
- package/dist/exceptions/range-not-satisfiable.js +2 -3
- package/dist/extensions.d.ts +1 -1
- package/dist/extensions.js +43 -33
- package/dist/flows.js +65 -46
- package/dist/logger.d.ts +2 -1
- package/dist/logger.js +35 -19
- package/dist/logger.test.d.ts +1 -0
- package/dist/mailer.js +16 -16
- package/dist/messenger.js +9 -7
- package/dist/middleware/authenticate.d.ts +1 -1
- package/dist/middleware/authenticate.js +13 -6
- package/dist/middleware/cache.d.ts +1 -1
- package/dist/middleware/cache.js +16 -16
- package/dist/middleware/check-ip.d.ts +1 -1
- package/dist/middleware/check-ip.js +1 -1
- package/dist/middleware/collection-exists.d.ts +1 -1
- package/dist/middleware/collection-exists.js +5 -5
- package/dist/middleware/cors.d.ts +1 -1
- package/dist/middleware/cors.js +7 -7
- package/dist/middleware/error-handler.d.ts +1 -1
- package/dist/middleware/error-handler.js +11 -12
- package/dist/middleware/extract-token.d.ts +1 -1
- package/dist/middleware/extract-token.js +2 -2
- package/dist/middleware/get-permissions.d.ts +1 -1
- package/dist/middleware/graphql.d.ts +1 -1
- package/dist/middleware/graphql.js +15 -9
- package/dist/middleware/rate-limiter-global.d.ts +5 -0
- package/dist/middleware/rate-limiter-global.js +48 -0
- package/dist/middleware/{rate-limiter.d.ts → rate-limiter-ip.d.ts} +2 -2
- package/dist/middleware/{rate-limiter.js → rate-limiter-ip.js} +5 -5
- package/dist/middleware/respond.d.ts +1 -1
- package/dist/middleware/respond.js +18 -19
- package/dist/middleware/sanitize-query.d.ts +1 -1
- package/dist/middleware/sanitize-query.js +1 -1
- package/dist/middleware/schema.d.ts +1 -1
- package/dist/middleware/use-collection.d.ts +1 -1
- package/dist/operations/condition/index.d.ts +1 -1
- package/dist/operations/exec/index.js +15 -4
- package/dist/operations/item-create/index.js +1 -2
- package/dist/operations/item-delete/index.d.ts +1 -1
- package/dist/operations/item-read/index.d.ts +1 -1
- package/dist/operations/item-update/index.d.ts +1 -1
- package/dist/operations/item-update/index.js +1 -2
- package/dist/operations/notification/index.js +1 -2
- package/dist/operations/request/index.js +19 -19
- package/dist/operations/trigger/index.js +2 -3
- package/dist/rate-limiter.d.ts +1 -1
- package/dist/rate-limiter.js +9 -9
- package/dist/request/validate-ip.js +2 -2
- package/dist/server.js +12 -13
- package/dist/services/activity.d.ts +1 -1
- package/dist/services/activity.js +17 -16
- package/dist/services/assets.d.ts +3 -3
- package/dist/services/assets.js +35 -37
- package/dist/services/authentication.d.ts +2 -2
- package/dist/services/authentication.js +22 -19
- package/dist/services/authorization.d.ts +3 -3
- package/dist/services/authorization.js +27 -31
- package/dist/services/collections.d.ts +5 -5
- package/dist/services/collections.js +54 -50
- package/dist/services/dashboards.d.ts +1 -1
- package/dist/services/fields.d.ts +5 -5
- package/dist/services/fields.js +50 -50
- package/dist/services/files.d.ts +1 -2
- package/dist/services/files.js +33 -27
- package/dist/services/flows.d.ts +2 -2
- package/dist/services/folders.d.ts +1 -1
- package/dist/services/graphql/index.d.ts +4 -4
- package/dist/services/graphql/index.js +259 -252
- package/dist/services/graphql/utils/add-path-to-validation-error.js +1 -2
- package/dist/services/graphql/utils/process-error.d.ts +2 -2
- package/dist/services/graphql/utils/process-error.js +11 -4
- package/dist/services/import-export.d.ts +3 -3
- package/dist/services/import-export.js +30 -27
- package/dist/services/items.d.ts +3 -3
- package/dist/services/items.js +42 -36
- package/dist/services/mail/index.d.ts +4 -4
- package/dist/services/mail/index.js +14 -10
- package/dist/services/meta.d.ts +3 -3
- package/dist/services/meta.js +11 -9
- package/dist/services/notifications.d.ts +3 -3
- package/dist/services/notifications.js +10 -9
- package/dist/services/operations.d.ts +2 -2
- package/dist/services/panels.d.ts +1 -1
- package/dist/services/payload.d.ts +3 -3
- package/dist/services/payload.js +124 -122
- package/dist/services/permissions.d.ts +3 -3
- package/dist/services/permissions.js +11 -11
- package/dist/services/presets.d.ts +1 -1
- package/dist/services/relations.d.ts +6 -6
- package/dist/services/relations.js +45 -43
- package/dist/services/revisions.d.ts +1 -1
- package/dist/services/revisions.js +3 -3
- package/dist/services/roles.d.ts +2 -2
- package/dist/services/roles.js +7 -7
- package/dist/services/schema.d.ts +3 -3
- package/dist/services/schema.js +9 -11
- package/dist/services/server.d.ts +3 -3
- package/dist/services/server.js +88 -32
- package/dist/services/settings.d.ts +1 -1
- package/dist/services/shares.d.ts +1 -1
- package/dist/services/shares.js +14 -15
- package/dist/services/specifications.d.ts +4 -4
- package/dist/services/specifications.js +137 -119
- package/dist/services/tfa.d.ts +2 -2
- package/dist/services/tfa.js +7 -5
- package/dist/services/users.d.ts +2 -6
- package/dist/services/users.js +37 -40
- package/dist/services/utils.d.ts +3 -3
- package/dist/services/utils.js +10 -8
- package/dist/services/webhooks.d.ts +2 -2
- package/dist/services/webhooks.js +2 -1
- package/dist/storage/register-locations.js +1 -1
- package/dist/types/assets.d.ts +1 -1
- package/dist/types/ast.d.ts +1 -1
- package/dist/types/auth.d.ts +2 -2
- package/dist/types/collection.d.ts +2 -2
- package/dist/types/events.d.ts +2 -2
- package/dist/types/graphql.d.ts +2 -2
- package/dist/types/items.d.ts +3 -3
- package/dist/types/services.d.ts +5 -5
- package/dist/types/snapshot.d.ts +4 -4
- package/dist/utils/apply-diff.d.ts +3 -3
- package/dist/utils/apply-diff.js +25 -28
- package/dist/utils/apply-query.d.ts +3 -3
- package/dist/utils/apply-query.js +10 -12
- package/dist/utils/apply-snapshot.d.ts +3 -3
- package/dist/utils/apply-snapshot.js +5 -6
- package/dist/utils/construct-flow-tree.d.ts +1 -1
- package/dist/utils/construct-flow-tree.js +2 -2
- package/dist/utils/dynamic-import.js +1 -1
- package/dist/utils/filter-items.d.ts +1 -1
- package/dist/utils/generate-hash.js +1 -1
- package/dist/utils/get-accountability-for-role.d.ts +2 -2
- package/dist/utils/get-accountability-for-role.js +1 -1
- package/dist/utils/get-ast-from-query.d.ts +3 -3
- package/dist/utils/get-ast-from-query.js +22 -28
- package/dist/utils/get-auth-providers.js +1 -1
- package/dist/utils/get-cache-headers.d.ts +1 -1
- package/dist/utils/get-cache-headers.js +6 -7
- package/dist/utils/get-cache-key.d.ts +1 -1
- package/dist/utils/get-cache-key.js +2 -3
- package/dist/utils/get-collection-from-alias.d.ts +1 -1
- package/dist/utils/get-collection-from-alias.js +1 -0
- package/dist/utils/get-column-path.d.ts +2 -2
- package/dist/utils/get-column-path.js +3 -4
- package/dist/utils/get-column.d.ts +4 -4
- package/dist/utils/get-column.js +4 -5
- package/dist/utils/get-default-value.d.ts +2 -2
- package/dist/utils/get-default-value.js +2 -3
- package/dist/utils/get-graphql-query-and-variables.d.ts +1 -1
- package/dist/utils/get-graphql-query-and-variables.js +1 -2
- package/dist/utils/get-graphql-type.d.ts +2 -2
- package/dist/utils/get-graphql-type.js +1 -1
- package/dist/utils/get-ip-from-req.d.ts +1 -1
- package/dist/utils/get-ip-from-req.js +2 -2
- package/dist/utils/get-local-type.d.ts +1 -1
- package/dist/utils/get-local-type.js +3 -3
- package/dist/utils/get-milliseconds.js +1 -2
- package/dist/utils/get-permissions.d.ts +1 -1
- package/dist/utils/get-permissions.js +12 -12
- package/dist/utils/get-relation-info.d.ts +1 -1
- package/dist/utils/get-relation-info.js +3 -5
- package/dist/utils/get-relation-type.d.ts +1 -1
- package/dist/utils/get-relation-type.js +3 -4
- package/dist/utils/get-schema.d.ts +2 -2
- package/dist/utils/get-schema.js +20 -22
- package/dist/utils/get-snapshot-diff.js +2 -3
- package/dist/utils/get-snapshot.d.ts +3 -3
- package/dist/utils/get-snapshot.js +6 -8
- package/dist/utils/is-directus-jwt.js +1 -1
- package/dist/utils/is-url-allowed.js +5 -2
- package/dist/utils/job-queue.js +2 -0
- package/dist/utils/jwt.d.ts +1 -1
- package/dist/utils/merge-permissions-for-share.d.ts +1 -1
- package/dist/utils/merge-permissions-for-share.js +3 -4
- package/dist/utils/merge-permissions.d.ts +3 -3
- package/dist/utils/reduce-schema.d.ts +1 -1
- package/dist/utils/reduce-schema.js +12 -12
- package/dist/utils/sanitize-query.d.ts +1 -1
- package/dist/utils/sanitize-query.js +27 -27
- package/dist/utils/sanitize-schema.d.ts +2 -2
- package/dist/utils/should-skip-cache.d.ts +7 -0
- package/dist/utils/should-skip-cache.js +21 -0
- package/dist/utils/should-skip-cache.test.d.ts +1 -0
- package/dist/utils/track.js +16 -16
- package/dist/utils/transformations.d.ts +1 -1
- package/dist/utils/transformations.js +2 -4
- package/dist/utils/url.js +7 -2
- package/dist/utils/user-name.d.ts +1 -1
- package/dist/utils/validate-diff.js +7 -8
- package/dist/utils/validate-keys.d.ts +2 -2
- package/dist/utils/validate-keys.js +1 -1
- package/dist/utils/validate-query.d.ts +1 -1
- package/dist/utils/validate-query.js +3 -3
- package/dist/utils/validate-storage.js +8 -8
- package/dist/webhooks.js +3 -3
- package/package.json +36 -37
- package/dist/utils/with-timeout.d.ts +0 -1
- package/dist/utils/with-timeout.js +0 -16
|
@@ -47,13 +47,17 @@ const get_milliseconds_1 = require("../../utils/get-milliseconds");
|
|
|
47
47
|
const url_1 = require("../../utils/url");
|
|
48
48
|
const local_1 = require("./local");
|
|
49
49
|
class OAuth2AuthDriver extends local_1.LocalAuthDriver {
|
|
50
|
+
client;
|
|
51
|
+
redirectUrl;
|
|
52
|
+
usersService;
|
|
53
|
+
config;
|
|
50
54
|
constructor(options, config) {
|
|
51
55
|
super(options, config);
|
|
52
56
|
const { authorizeUrl, accessUrl, profileUrl, clientId, clientSecret, ...additionalConfig } = config;
|
|
53
|
-
if (!authorizeUrl || !accessUrl || !profileUrl || !clientId || !clientSecret || !additionalConfig
|
|
54
|
-
throw new exceptions_2.InvalidConfigException('Invalid provider config', { provider: additionalConfig
|
|
57
|
+
if (!authorizeUrl || !accessUrl || !profileUrl || !clientId || !clientSecret || !additionalConfig['provider']) {
|
|
58
|
+
throw new exceptions_2.InvalidConfigException('Invalid provider config', { provider: additionalConfig['provider'] });
|
|
55
59
|
}
|
|
56
|
-
const redirectUrl = new url_1.Url(env_1.default
|
|
60
|
+
const redirectUrl = new url_1.Url(env_1.default['PUBLIC_URL']).addPath('auth', 'login', additionalConfig['provider'], 'callback');
|
|
57
61
|
this.redirectUrl = redirectUrl.toString();
|
|
58
62
|
this.usersService = new services_1.UsersService({ knex: this.knex, schema: this.schema });
|
|
59
63
|
this.config = additionalConfig;
|
|
@@ -61,9 +65,9 @@ class OAuth2AuthDriver extends local_1.LocalAuthDriver {
|
|
|
61
65
|
authorization_endpoint: authorizeUrl,
|
|
62
66
|
token_endpoint: accessUrl,
|
|
63
67
|
userinfo_endpoint: profileUrl,
|
|
64
|
-
issuer: additionalConfig
|
|
68
|
+
issuer: additionalConfig['provider'],
|
|
65
69
|
});
|
|
66
|
-
const clientOptionsOverrides = (0, get_config_from_env_1.getConfigFromEnv)(`AUTH_${config
|
|
70
|
+
const clientOptionsOverrides = (0, get_config_from_env_1.getConfigFromEnv)(`AUTH_${config['provider'].toUpperCase()}_CLIENT_`, [`AUTH_${config['provider'].toUpperCase()}_CLIENT_ID`, `AUTH_${config['provider'].toUpperCase()}_CLIENT_SECRET`], 'underscore');
|
|
67
71
|
this.client = new issuer.Client({
|
|
68
72
|
client_id: clientId,
|
|
69
73
|
client_secret: clientSecret,
|
|
@@ -76,12 +80,11 @@ class OAuth2AuthDriver extends local_1.LocalAuthDriver {
|
|
|
76
80
|
return openid_client_1.generators.codeVerifier();
|
|
77
81
|
}
|
|
78
82
|
generateAuthUrl(codeVerifier, prompt = false) {
|
|
79
|
-
var _a;
|
|
80
83
|
try {
|
|
81
84
|
const codeChallenge = openid_client_1.generators.codeChallenge(codeVerifier);
|
|
82
|
-
const paramsConfig = typeof this.config
|
|
85
|
+
const paramsConfig = typeof this.config['params'] === 'object' ? this.config['params'] : {};
|
|
83
86
|
return this.client.authorizationUrl({
|
|
84
|
-
scope:
|
|
87
|
+
scope: this.config['scope'] ?? 'email',
|
|
85
88
|
access_type: 'offline',
|
|
86
89
|
prompt: prompt ? 'consent' : undefined,
|
|
87
90
|
...paramsConfig,
|
|
@@ -101,17 +104,17 @@ class OAuth2AuthDriver extends local_1.LocalAuthDriver {
|
|
|
101
104
|
.from('directus_users')
|
|
102
105
|
.whereRaw('LOWER(??) = ?', ['external_identifier', identifier.toLowerCase()])
|
|
103
106
|
.first();
|
|
104
|
-
return user
|
|
107
|
+
return user?.id;
|
|
105
108
|
}
|
|
106
109
|
async getUserID(payload) {
|
|
107
|
-
if (!payload
|
|
110
|
+
if (!payload['code'] || !payload['codeVerifier'] || !payload['state']) {
|
|
108
111
|
logger_1.default.warn('[OAuth2] No code, codeVerifier or state in payload');
|
|
109
112
|
throw new exceptions_2.InvalidCredentialsException();
|
|
110
113
|
}
|
|
111
114
|
let tokenSet;
|
|
112
115
|
let userInfo;
|
|
113
116
|
try {
|
|
114
|
-
tokenSet = await this.client.oauthCallback(this.redirectUrl, { code: payload
|
|
117
|
+
tokenSet = await this.client.oauthCallback(this.redirectUrl, { code: payload['code'], state: payload['state'] }, { code_verifier: payload['codeVerifier'], state: openid_client_1.generators.codeChallenge(payload['codeVerifier']) });
|
|
115
118
|
userInfo = await this.client.userinfo(tokenSet.access_token);
|
|
116
119
|
}
|
|
117
120
|
catch (e) {
|
|
@@ -120,7 +123,7 @@ class OAuth2AuthDriver extends local_1.LocalAuthDriver {
|
|
|
120
123
|
// Flatten response to support dot indexes
|
|
121
124
|
userInfo = (0, flat_1.default)(userInfo);
|
|
122
125
|
const { provider, emailKey, identifierKey, allowPublicRegistration } = this.config;
|
|
123
|
-
const email = userInfo[emailKey
|
|
126
|
+
const email = userInfo[emailKey ?? 'email'] ? String(userInfo[emailKey ?? 'email']) : undefined;
|
|
124
127
|
// Fallback to email if explicit identifier not found
|
|
125
128
|
const identifier = userInfo[identifierKey] ? String(userInfo[identifierKey]) : email;
|
|
126
129
|
if (!identifier) {
|
|
@@ -145,11 +148,11 @@ class OAuth2AuthDriver extends local_1.LocalAuthDriver {
|
|
|
145
148
|
try {
|
|
146
149
|
await this.usersService.createOne({
|
|
147
150
|
provider,
|
|
148
|
-
first_name: userInfo[this.config
|
|
149
|
-
last_name: userInfo[this.config
|
|
151
|
+
first_name: userInfo[this.config['firstNameKey']],
|
|
152
|
+
last_name: userInfo[this.config['lastNameKey']],
|
|
150
153
|
email: email,
|
|
151
154
|
external_identifier: identifier,
|
|
152
|
-
role: this.config
|
|
155
|
+
role: this.config['defaultRoleId'],
|
|
153
156
|
auth_data: tokenSet.refresh_token && JSON.stringify({ refreshToken: tokenSet.refresh_token }),
|
|
154
157
|
});
|
|
155
158
|
}
|
|
@@ -175,9 +178,9 @@ class OAuth2AuthDriver extends local_1.LocalAuthDriver {
|
|
|
175
178
|
logger_1.default.warn(`[OAuth2] Session data isn't valid JSON: ${authData}`);
|
|
176
179
|
}
|
|
177
180
|
}
|
|
178
|
-
if (authData
|
|
181
|
+
if (authData?.['refreshToken']) {
|
|
179
182
|
try {
|
|
180
|
-
const tokenSet = await this.client.refresh(authData
|
|
183
|
+
const tokenSet = await this.client.refresh(authData['refreshToken']);
|
|
181
184
|
// Update user refreshToken if provided
|
|
182
185
|
if (tokenSet.refresh_token) {
|
|
183
186
|
await this.usersService.updateOne(user.id, {
|
|
@@ -219,8 +222,8 @@ function createOAuth2AuthRouter(providerName) {
|
|
|
219
222
|
router.get('/', (req, res) => {
|
|
220
223
|
const provider = (0, auth_1.getAuthProvider)(providerName);
|
|
221
224
|
const codeVerifier = provider.generateCodeVerifier();
|
|
222
|
-
const prompt = !!req.query
|
|
223
|
-
const token = jsonwebtoken_1.default.sign({ verifier: codeVerifier, redirect: req.query
|
|
225
|
+
const prompt = !!req.query['prompt'];
|
|
226
|
+
const token = jsonwebtoken_1.default.sign({ verifier: codeVerifier, redirect: req.query['redirect'], prompt }, env_1.default['SECRET'], {
|
|
224
227
|
expiresIn: '5m',
|
|
225
228
|
issuer: 'directus',
|
|
226
229
|
});
|
|
@@ -234,32 +237,38 @@ function createOAuth2AuthRouter(providerName) {
|
|
|
234
237
|
res.redirect(303, `./callback?${new URLSearchParams(req.body)}`);
|
|
235
238
|
}, respond_1.respond);
|
|
236
239
|
router.get('/callback', (0, async_handler_1.default)(async (req, res, next) => {
|
|
237
|
-
var _a;
|
|
238
240
|
let tokenData;
|
|
239
241
|
try {
|
|
240
|
-
tokenData = jsonwebtoken_1.default.verify(req.cookies[`oauth2.${providerName}`], env_1.default
|
|
242
|
+
tokenData = jsonwebtoken_1.default.verify(req.cookies[`oauth2.${providerName}`], env_1.default['SECRET'], {
|
|
243
|
+
issuer: 'directus',
|
|
244
|
+
});
|
|
241
245
|
}
|
|
242
246
|
catch (e) {
|
|
243
247
|
logger_1.default.warn(e, `[OAuth2] Couldn't verify OAuth2 cookie`);
|
|
244
248
|
throw new exceptions_2.InvalidCredentialsException();
|
|
245
249
|
}
|
|
246
250
|
const { verifier, redirect, prompt } = tokenData;
|
|
251
|
+
const accountability = {
|
|
252
|
+
ip: (0, get_ip_from_req_1.getIPFromReq)(req),
|
|
253
|
+
role: null,
|
|
254
|
+
};
|
|
255
|
+
const userAgent = req.get('user-agent');
|
|
256
|
+
if (userAgent)
|
|
257
|
+
accountability.userAgent = userAgent;
|
|
258
|
+
const origin = req.get('origin');
|
|
259
|
+
if (origin)
|
|
260
|
+
accountability.origin = origin;
|
|
247
261
|
const authenticationService = new services_1.AuthenticationService({
|
|
248
|
-
accountability
|
|
249
|
-
ip: (0, get_ip_from_req_1.getIPFromReq)(req),
|
|
250
|
-
userAgent: req.get('user-agent'),
|
|
251
|
-
origin: req.get('origin'),
|
|
252
|
-
role: null,
|
|
253
|
-
},
|
|
262
|
+
accountability,
|
|
254
263
|
schema: req.schema,
|
|
255
264
|
});
|
|
256
265
|
let authResponse;
|
|
257
266
|
try {
|
|
258
267
|
res.clearCookie(`oauth2.${providerName}`);
|
|
259
268
|
authResponse = await authenticationService.login(providerName, {
|
|
260
|
-
code: req.query
|
|
269
|
+
code: req.query['code'],
|
|
261
270
|
codeVerifier: verifier,
|
|
262
|
-
state: req.query
|
|
271
|
+
state: req.query['state'],
|
|
263
272
|
});
|
|
264
273
|
}
|
|
265
274
|
catch (error) {
|
|
@@ -282,16 +291,16 @@ function createOAuth2AuthRouter(providerName) {
|
|
|
282
291
|
}
|
|
283
292
|
const { accessToken, refreshToken, expires } = authResponse;
|
|
284
293
|
if (redirect) {
|
|
285
|
-
res.cookie(env_1.default
|
|
294
|
+
res.cookie(env_1.default['REFRESH_TOKEN_COOKIE_NAME'], refreshToken, {
|
|
286
295
|
httpOnly: true,
|
|
287
|
-
domain: env_1.default
|
|
288
|
-
maxAge: (0, get_milliseconds_1.getMilliseconds)(env_1.default
|
|
289
|
-
secure:
|
|
290
|
-
sameSite: env_1.default
|
|
296
|
+
domain: env_1.default['REFRESH_TOKEN_COOKIE_DOMAIN'],
|
|
297
|
+
maxAge: (0, get_milliseconds_1.getMilliseconds)(env_1.default['REFRESH_TOKEN_TTL']),
|
|
298
|
+
secure: env_1.default['REFRESH_TOKEN_COOKIE_SECURE'] ?? false,
|
|
299
|
+
sameSite: env_1.default['REFRESH_TOKEN_COOKIE_SAME_SITE'] || 'strict',
|
|
291
300
|
});
|
|
292
301
|
return res.redirect(redirect);
|
|
293
302
|
}
|
|
294
|
-
res.locals
|
|
303
|
+
res.locals['payload'] = {
|
|
295
304
|
data: { access_token: accessToken, refresh_token: refreshToken, expires },
|
|
296
305
|
};
|
|
297
306
|
next();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
2
|
import { Client } from 'openid-client';
|
|
3
3
|
import { UsersService } from '../../services';
|
|
4
|
-
import { AuthDriverOptions, User } from '../../types';
|
|
4
|
+
import type { AuthDriverOptions, User } from '../../types';
|
|
5
5
|
import { LocalAuthDriver } from './local';
|
|
6
6
|
export declare class OpenIDAuthDriver extends LocalAuthDriver {
|
|
7
7
|
client: Promise<Client>;
|
|
@@ -47,24 +47,28 @@ const get_milliseconds_1 = require("../../utils/get-milliseconds");
|
|
|
47
47
|
const url_1 = require("../../utils/url");
|
|
48
48
|
const local_1 = require("./local");
|
|
49
49
|
class OpenIDAuthDriver extends local_1.LocalAuthDriver {
|
|
50
|
+
client;
|
|
51
|
+
redirectUrl;
|
|
52
|
+
usersService;
|
|
53
|
+
config;
|
|
50
54
|
constructor(options, config) {
|
|
51
55
|
super(options, config);
|
|
52
56
|
const { issuerUrl, clientId, clientSecret, ...additionalConfig } = config;
|
|
53
|
-
if (!issuerUrl || !clientId || !clientSecret || !additionalConfig
|
|
54
|
-
throw new exceptions_2.InvalidConfigException('Invalid provider config', { provider: additionalConfig
|
|
57
|
+
if (!issuerUrl || !clientId || !clientSecret || !additionalConfig['provider']) {
|
|
58
|
+
throw new exceptions_2.InvalidConfigException('Invalid provider config', { provider: additionalConfig['provider'] });
|
|
55
59
|
}
|
|
56
|
-
const redirectUrl = new url_1.Url(env_1.default
|
|
57
|
-
const clientOptionsOverrides = (0, get_config_from_env_1.getConfigFromEnv)(`AUTH_${config
|
|
60
|
+
const redirectUrl = new url_1.Url(env_1.default['PUBLIC_URL']).addPath('auth', 'login', additionalConfig['provider'], 'callback');
|
|
61
|
+
const clientOptionsOverrides = (0, get_config_from_env_1.getConfigFromEnv)(`AUTH_${config['provider'].toUpperCase()}_CLIENT_`, [`AUTH_${config['provider'].toUpperCase()}_CLIENT_ID`, `AUTH_${config['provider'].toUpperCase()}_CLIENT_SECRET`], 'underscore');
|
|
58
62
|
this.redirectUrl = redirectUrl.toString();
|
|
59
63
|
this.usersService = new services_1.UsersService({ knex: this.knex, schema: this.schema });
|
|
60
64
|
this.config = additionalConfig;
|
|
61
65
|
this.client = new Promise((resolve, reject) => {
|
|
62
66
|
openid_client_1.Issuer.discover(issuerUrl)
|
|
63
67
|
.then((issuer) => {
|
|
64
|
-
const supportedTypes = issuer.metadata
|
|
65
|
-
if (!
|
|
68
|
+
const supportedTypes = issuer.metadata['response_types_supported'];
|
|
69
|
+
if (!supportedTypes?.includes('code')) {
|
|
66
70
|
reject(new exceptions_2.InvalidConfigException('OpenID provider does not support required code flow', {
|
|
67
|
-
provider: additionalConfig
|
|
71
|
+
provider: additionalConfig['provider'],
|
|
68
72
|
}));
|
|
69
73
|
}
|
|
70
74
|
resolve(new issuer.Client({
|
|
@@ -85,13 +89,12 @@ class OpenIDAuthDriver extends local_1.LocalAuthDriver {
|
|
|
85
89
|
return openid_client_1.generators.codeVerifier();
|
|
86
90
|
}
|
|
87
91
|
async generateAuthUrl(codeVerifier, prompt = false) {
|
|
88
|
-
var _a;
|
|
89
92
|
try {
|
|
90
93
|
const client = await this.client;
|
|
91
94
|
const codeChallenge = openid_client_1.generators.codeChallenge(codeVerifier);
|
|
92
|
-
const paramsConfig = typeof this.config
|
|
95
|
+
const paramsConfig = typeof this.config['params'] === 'object' ? this.config['params'] : {};
|
|
93
96
|
return client.authorizationUrl({
|
|
94
|
-
scope:
|
|
97
|
+
scope: this.config['scope'] ?? 'openid profile email',
|
|
95
98
|
access_type: 'offline',
|
|
96
99
|
prompt: prompt ? 'consent' : undefined,
|
|
97
100
|
...paramsConfig,
|
|
@@ -112,10 +115,10 @@ class OpenIDAuthDriver extends local_1.LocalAuthDriver {
|
|
|
112
115
|
.from('directus_users')
|
|
113
116
|
.whereRaw('LOWER(??) = ?', ['external_identifier', identifier.toLowerCase()])
|
|
114
117
|
.first();
|
|
115
|
-
return user
|
|
118
|
+
return user?.id;
|
|
116
119
|
}
|
|
117
120
|
async getUserID(payload) {
|
|
118
|
-
if (!payload
|
|
121
|
+
if (!payload['code'] || !payload['codeVerifier'] || !payload['state']) {
|
|
119
122
|
logger_1.default.warn('[OpenID] No code, codeVerifier or state in payload');
|
|
120
123
|
throw new exceptions_2.InvalidCredentialsException();
|
|
121
124
|
}
|
|
@@ -123,10 +126,10 @@ class OpenIDAuthDriver extends local_1.LocalAuthDriver {
|
|
|
123
126
|
let userInfo;
|
|
124
127
|
try {
|
|
125
128
|
const client = await this.client;
|
|
126
|
-
const codeChallenge = openid_client_1.generators.codeChallenge(payload
|
|
127
|
-
tokenSet = await client.callback(this.redirectUrl, { code: payload
|
|
129
|
+
const codeChallenge = openid_client_1.generators.codeChallenge(payload['codeVerifier']);
|
|
130
|
+
tokenSet = await client.callback(this.redirectUrl, { code: payload['code'], state: payload['state'] }, { code_verifier: payload['codeVerifier'], state: codeChallenge, nonce: codeChallenge });
|
|
128
131
|
userInfo = tokenSet.claims();
|
|
129
|
-
if (client.issuer.metadata
|
|
132
|
+
if (client.issuer.metadata['userinfo_endpoint']) {
|
|
130
133
|
userInfo = {
|
|
131
134
|
...userInfo,
|
|
132
135
|
...(await client.userinfo(tokenSet.access_token)),
|
|
@@ -139,9 +142,9 @@ class OpenIDAuthDriver extends local_1.LocalAuthDriver {
|
|
|
139
142
|
// Flatten response to support dot indexes
|
|
140
143
|
userInfo = (0, flat_1.default)(userInfo);
|
|
141
144
|
const { provider, identifierKey, allowPublicRegistration, requireVerifiedEmail } = this.config;
|
|
142
|
-
const email = userInfo
|
|
145
|
+
const email = userInfo['email'] ? String(userInfo['email']) : undefined;
|
|
143
146
|
// Fallback to email if explicit identifier not found
|
|
144
|
-
const identifier = userInfo[identifierKey
|
|
147
|
+
const identifier = userInfo[identifierKey ?? 'sub'] ? String(userInfo[identifierKey ?? 'sub']) : email;
|
|
145
148
|
if (!identifier) {
|
|
146
149
|
logger_1.default.warn(`[OpenID] Failed to find user identifier for provider "${provider}"`);
|
|
147
150
|
throw new exceptions_2.InvalidCredentialsException();
|
|
@@ -156,7 +159,7 @@ class OpenIDAuthDriver extends local_1.LocalAuthDriver {
|
|
|
156
159
|
}
|
|
157
160
|
return userId;
|
|
158
161
|
}
|
|
159
|
-
const isEmailVerified = !requireVerifiedEmail || userInfo
|
|
162
|
+
const isEmailVerified = !requireVerifiedEmail || userInfo['email_verified'];
|
|
160
163
|
// Is public registration allowed?
|
|
161
164
|
if (!allowPublicRegistration || !isEmailVerified) {
|
|
162
165
|
logger_1.default.warn(`[OpenID] User doesn't exist, and public registration not allowed for provider "${provider}"`);
|
|
@@ -165,11 +168,11 @@ class OpenIDAuthDriver extends local_1.LocalAuthDriver {
|
|
|
165
168
|
try {
|
|
166
169
|
await this.usersService.createOne({
|
|
167
170
|
provider,
|
|
168
|
-
first_name: userInfo
|
|
169
|
-
last_name: userInfo
|
|
171
|
+
first_name: userInfo['given_name'],
|
|
172
|
+
last_name: userInfo['family_name'],
|
|
170
173
|
email: email,
|
|
171
174
|
external_identifier: identifier,
|
|
172
|
-
role: this.config
|
|
175
|
+
role: this.config['defaultRoleId'],
|
|
173
176
|
auth_data: tokenSet.refresh_token && JSON.stringify({ refreshToken: tokenSet.refresh_token }),
|
|
174
177
|
});
|
|
175
178
|
}
|
|
@@ -195,10 +198,10 @@ class OpenIDAuthDriver extends local_1.LocalAuthDriver {
|
|
|
195
198
|
logger_1.default.warn(`[OpenID] Session data isn't valid JSON: ${authData}`);
|
|
196
199
|
}
|
|
197
200
|
}
|
|
198
|
-
if (authData
|
|
201
|
+
if (authData?.['refreshToken']) {
|
|
199
202
|
try {
|
|
200
203
|
const client = await this.client;
|
|
201
|
-
const tokenSet = await client.refresh(authData
|
|
204
|
+
const tokenSet = await client.refresh(authData['refreshToken']);
|
|
202
205
|
// Update user refreshToken if provided
|
|
203
206
|
if (tokenSet.refresh_token) {
|
|
204
207
|
await this.usersService.updateOne(user.id, {
|
|
@@ -240,8 +243,8 @@ function createOpenIDAuthRouter(providerName) {
|
|
|
240
243
|
router.get('/', (0, async_handler_1.default)(async (req, res) => {
|
|
241
244
|
const provider = (0, auth_1.getAuthProvider)(providerName);
|
|
242
245
|
const codeVerifier = provider.generateCodeVerifier();
|
|
243
|
-
const prompt = !!req.query
|
|
244
|
-
const token = jsonwebtoken_1.default.sign({ verifier: codeVerifier, redirect: req.query
|
|
246
|
+
const prompt = !!req.query['prompt'];
|
|
247
|
+
const token = jsonwebtoken_1.default.sign({ verifier: codeVerifier, redirect: req.query['redirect'], prompt }, env_1.default['SECRET'], {
|
|
245
248
|
expiresIn: '5m',
|
|
246
249
|
issuer: 'directus',
|
|
247
250
|
});
|
|
@@ -255,32 +258,38 @@ function createOpenIDAuthRouter(providerName) {
|
|
|
255
258
|
res.redirect(303, `./callback?${new URLSearchParams(req.body)}`);
|
|
256
259
|
}, respond_1.respond);
|
|
257
260
|
router.get('/callback', (0, async_handler_1.default)(async (req, res, next) => {
|
|
258
|
-
var _a;
|
|
259
261
|
let tokenData;
|
|
260
262
|
try {
|
|
261
|
-
tokenData = jsonwebtoken_1.default.verify(req.cookies[`openid.${providerName}`], env_1.default
|
|
263
|
+
tokenData = jsonwebtoken_1.default.verify(req.cookies[`openid.${providerName}`], env_1.default['SECRET'], {
|
|
264
|
+
issuer: 'directus',
|
|
265
|
+
});
|
|
262
266
|
}
|
|
263
267
|
catch (e) {
|
|
264
268
|
logger_1.default.warn(e, `[OpenID] Couldn't verify OpenID cookie`);
|
|
265
269
|
throw new exceptions_2.InvalidCredentialsException();
|
|
266
270
|
}
|
|
267
271
|
const { verifier, redirect, prompt } = tokenData;
|
|
272
|
+
const accountability = {
|
|
273
|
+
ip: (0, get_ip_from_req_1.getIPFromReq)(req),
|
|
274
|
+
role: null,
|
|
275
|
+
};
|
|
276
|
+
const userAgent = req.get('user-agent');
|
|
277
|
+
if (userAgent)
|
|
278
|
+
accountability.userAgent = userAgent;
|
|
279
|
+
const origin = req.get('origin');
|
|
280
|
+
if (origin)
|
|
281
|
+
accountability.origin = origin;
|
|
268
282
|
const authenticationService = new services_1.AuthenticationService({
|
|
269
|
-
accountability
|
|
270
|
-
ip: (0, get_ip_from_req_1.getIPFromReq)(req),
|
|
271
|
-
userAgent: req.get('user-agent'),
|
|
272
|
-
origin: req.get('origin'),
|
|
273
|
-
role: null,
|
|
274
|
-
},
|
|
283
|
+
accountability,
|
|
275
284
|
schema: req.schema,
|
|
276
285
|
});
|
|
277
286
|
let authResponse;
|
|
278
287
|
try {
|
|
279
288
|
res.clearCookie(`openid.${providerName}`);
|
|
280
289
|
authResponse = await authenticationService.login(providerName, {
|
|
281
|
-
code: req.query
|
|
290
|
+
code: req.query['code'],
|
|
282
291
|
codeVerifier: verifier,
|
|
283
|
-
state: req.query
|
|
292
|
+
state: req.query['state'],
|
|
284
293
|
});
|
|
285
294
|
}
|
|
286
295
|
catch (error) {
|
|
@@ -304,16 +313,16 @@ function createOpenIDAuthRouter(providerName) {
|
|
|
304
313
|
}
|
|
305
314
|
const { accessToken, refreshToken, expires } = authResponse;
|
|
306
315
|
if (redirect) {
|
|
307
|
-
res.cookie(env_1.default
|
|
316
|
+
res.cookie(env_1.default['REFRESH_TOKEN_COOKIE_NAME'], refreshToken, {
|
|
308
317
|
httpOnly: true,
|
|
309
|
-
domain: env_1.default
|
|
310
|
-
maxAge: (0, get_milliseconds_1.getMilliseconds)(env_1.default
|
|
311
|
-
secure:
|
|
312
|
-
sameSite: env_1.default
|
|
318
|
+
domain: env_1.default['REFRESH_TOKEN_COOKIE_DOMAIN'],
|
|
319
|
+
maxAge: (0, get_milliseconds_1.getMilliseconds)(env_1.default['REFRESH_TOKEN_TTL']),
|
|
320
|
+
secure: env_1.default['REFRESH_TOKEN_COOKIE_SECURE'] ?? false,
|
|
321
|
+
sameSite: env_1.default['REFRESH_TOKEN_COOKIE_SAME_SITE'] || 'strict',
|
|
313
322
|
});
|
|
314
323
|
return res.redirect(redirect);
|
|
315
324
|
}
|
|
316
|
-
res.locals
|
|
325
|
+
res.locals['payload'] = {
|
|
317
326
|
data: { access_token: accessToken, refresh_token: refreshToken, expires },
|
|
318
327
|
};
|
|
319
328
|
next();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { UsersService } from '../../services';
|
|
2
|
-
import { AuthDriverOptions, User } from '../../types';
|
|
2
|
+
import type { AuthDriverOptions, User } from '../../types';
|
|
3
3
|
import { LocalAuthDriver } from './local';
|
|
4
4
|
export declare class SAMLAuthDriver extends LocalAuthDriver {
|
|
5
5
|
idp: any;
|
|
@@ -45,12 +45,16 @@ const local_1 = require("./local");
|
|
|
45
45
|
// tell samlify to use validator...
|
|
46
46
|
samlify.setSchemaValidator(validator);
|
|
47
47
|
class SAMLAuthDriver extends local_1.LocalAuthDriver {
|
|
48
|
+
idp;
|
|
49
|
+
sp;
|
|
50
|
+
usersService;
|
|
51
|
+
config;
|
|
48
52
|
constructor(options, config) {
|
|
49
53
|
super(options, config);
|
|
50
54
|
this.config = config;
|
|
51
55
|
this.usersService = new services_1.UsersService({ knex: this.knex, schema: this.schema });
|
|
52
|
-
this.sp = samlify.ServiceProvider((0, get_config_from_env_1.getConfigFromEnv)(`AUTH_${config
|
|
53
|
-
this.idp = samlify.IdentityProvider((0, get_config_from_env_1.getConfigFromEnv)(`AUTH_${config
|
|
56
|
+
this.sp = samlify.ServiceProvider((0, get_config_from_env_1.getConfigFromEnv)(`AUTH_${config['provider'].toUpperCase()}_SP`));
|
|
57
|
+
this.idp = samlify.IdentityProvider((0, get_config_from_env_1.getConfigFromEnv)(`AUTH_${config['provider'].toUpperCase()}_IDP`));
|
|
54
58
|
}
|
|
55
59
|
async fetchUserID(identifier) {
|
|
56
60
|
const user = await this.knex
|
|
@@ -58,12 +62,12 @@ class SAMLAuthDriver extends local_1.LocalAuthDriver {
|
|
|
58
62
|
.from('directus_users')
|
|
59
63
|
.whereRaw('LOWER(??) = ?', ['external_identifier', identifier.toLowerCase()])
|
|
60
64
|
.first();
|
|
61
|
-
return user
|
|
65
|
+
return user?.id;
|
|
62
66
|
}
|
|
63
67
|
async getUserID(payload) {
|
|
64
68
|
const { provider, emailKey, identifierKey, givenNameKey, familyNameKey, allowPublicRegistration } = this.config;
|
|
65
|
-
const email = payload[emailKey
|
|
66
|
-
const identifier = payload[identifierKey
|
|
69
|
+
const email = payload[emailKey ?? 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress'];
|
|
70
|
+
const identifier = payload[identifierKey ?? 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier'];
|
|
67
71
|
const userID = await this.fetchUserID(identifier);
|
|
68
72
|
if (userID)
|
|
69
73
|
return userID;
|
|
@@ -71,8 +75,8 @@ class SAMLAuthDriver extends local_1.LocalAuthDriver {
|
|
|
71
75
|
logger_1.default.trace(`[SAML] User doesn't exist, and public registration not allowed for provider "${provider}"`);
|
|
72
76
|
throw new exceptions_2.InvalidCredentialsException();
|
|
73
77
|
}
|
|
74
|
-
const firstName = payload[givenNameKey
|
|
75
|
-
const lastName = payload[familyNameKey
|
|
78
|
+
const firstName = payload[givenNameKey ?? 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname'];
|
|
79
|
+
const lastName = payload[familyNameKey ?? 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname'];
|
|
76
80
|
try {
|
|
77
81
|
return await this.usersService.createOne({
|
|
78
82
|
provider,
|
|
@@ -80,7 +84,7 @@ class SAMLAuthDriver extends local_1.LocalAuthDriver {
|
|
|
80
84
|
last_name: lastName,
|
|
81
85
|
email: email,
|
|
82
86
|
external_identifier: identifier.toLowerCase(),
|
|
83
|
-
role: this.config
|
|
87
|
+
role: this.config['defaultRoleId'],
|
|
84
88
|
});
|
|
85
89
|
}
|
|
86
90
|
catch (error) {
|
|
@@ -107,8 +111,8 @@ function createSAMLAuthRouter(providerName) {
|
|
|
107
111
|
const { sp, idp } = (0, auth_1.getAuthProvider)(providerName);
|
|
108
112
|
const { context: url } = await sp.createLoginRequest(idp, 'redirect');
|
|
109
113
|
const parsedUrl = new URL(url);
|
|
110
|
-
if (req.query
|
|
111
|
-
parsedUrl.searchParams.append('RelayState', req.query
|
|
114
|
+
if (req.query['redirect']) {
|
|
115
|
+
parsedUrl.searchParams.append('RelayState', req.query['redirect']);
|
|
112
116
|
}
|
|
113
117
|
return res.redirect(parsedUrl.toString());
|
|
114
118
|
}));
|
|
@@ -116,24 +120,23 @@ function createSAMLAuthRouter(providerName) {
|
|
|
116
120
|
const { sp, idp } = (0, auth_1.getAuthProvider)(providerName);
|
|
117
121
|
const { context } = await sp.createLogoutRequest(idp, 'redirect', req.body);
|
|
118
122
|
const authService = new services_1.AuthenticationService({ accountability: req.accountability, schema: req.schema });
|
|
119
|
-
if (req.cookies[env_1.default
|
|
120
|
-
const currentRefreshToken = req.cookies[env_1.default
|
|
123
|
+
if (req.cookies[env_1.default['REFRESH_TOKEN_COOKIE_NAME']]) {
|
|
124
|
+
const currentRefreshToken = req.cookies[env_1.default['REFRESH_TOKEN_COOKIE_NAME']];
|
|
121
125
|
if (currentRefreshToken) {
|
|
122
126
|
await authService.logout(currentRefreshToken);
|
|
123
|
-
res.clearCookie(env_1.default
|
|
127
|
+
res.clearCookie(env_1.default['REFRESH_TOKEN_COOKIE_NAME'], constants_1.COOKIE_OPTIONS);
|
|
124
128
|
}
|
|
125
129
|
}
|
|
126
130
|
return res.redirect(context);
|
|
127
131
|
}));
|
|
128
132
|
router.post('/acs', express_1.default.urlencoded({ extended: false }), (0, async_handler_1.default)(async (req, res, next) => {
|
|
129
|
-
|
|
130
|
-
const relayState = (_a = req.body) === null || _a === void 0 ? void 0 : _a.RelayState;
|
|
133
|
+
const relayState = req.body?.RelayState;
|
|
131
134
|
try {
|
|
132
135
|
const { sp, idp } = (0, auth_1.getAuthProvider)(providerName);
|
|
133
136
|
const { extract } = await sp.parseLoginResponse(idp, 'post', req);
|
|
134
137
|
const authService = new services_1.AuthenticationService({ accountability: req.accountability, schema: req.schema });
|
|
135
138
|
const { accessToken, refreshToken, expires } = await authService.login(providerName, extract.attributes);
|
|
136
|
-
res.locals
|
|
139
|
+
res.locals['payload'] = {
|
|
137
140
|
data: {
|
|
138
141
|
access_token: accessToken,
|
|
139
142
|
refresh_token: refreshToken,
|
|
@@ -141,7 +144,7 @@ function createSAMLAuthRouter(providerName) {
|
|
|
141
144
|
},
|
|
142
145
|
};
|
|
143
146
|
if (relayState) {
|
|
144
|
-
res.cookie(env_1.default
|
|
147
|
+
res.cookie(env_1.default['REFRESH_TOKEN_COOKIE_NAME'], refreshToken, constants_1.COOKIE_OPTIONS);
|
|
145
148
|
return res.redirect(relayState);
|
|
146
149
|
}
|
|
147
150
|
return next();
|
package/dist/auth.d.ts
CHANGED
package/dist/auth.js
CHANGED
|
@@ -4,16 +4,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.registerAuthProviders = exports.getAuthProvider = void 0;
|
|
7
|
-
const
|
|
8
|
-
const env_1 = __importDefault(require("./env"));
|
|
9
|
-
const logger_1 = __importDefault(require("./logger"));
|
|
7
|
+
const utils_1 = require("@directus/shared/utils");
|
|
10
8
|
const drivers_1 = require("./auth/drivers");
|
|
11
9
|
const constants_1 = require("./constants");
|
|
10
|
+
const database_1 = __importDefault(require("./database"));
|
|
11
|
+
const env_1 = __importDefault(require("./env"));
|
|
12
12
|
const exceptions_1 = require("./exceptions");
|
|
13
|
+
const logger_1 = __importDefault(require("./logger"));
|
|
13
14
|
const get_config_from_env_1 = require("./utils/get-config-from-env");
|
|
14
15
|
const get_schema_1 = require("./utils/get-schema");
|
|
15
|
-
const
|
|
16
|
-
const providerNames = (0, utils_1.toArray)(env_1.default.AUTH_PROVIDERS);
|
|
16
|
+
const providerNames = (0, utils_1.toArray)(env_1.default['AUTH_PROVIDERS']);
|
|
17
17
|
const providers = new Map();
|
|
18
18
|
function getAuthProvider(provider) {
|
|
19
19
|
if (!providers.has(provider)) {
|
|
@@ -25,11 +25,11 @@ exports.getAuthProvider = getAuthProvider;
|
|
|
25
25
|
async function registerAuthProviders() {
|
|
26
26
|
const options = { knex: (0, database_1.default)(), schema: await (0, get_schema_1.getSchema)() };
|
|
27
27
|
// Register default provider if not disabled
|
|
28
|
-
if (!env_1.default
|
|
28
|
+
if (!env_1.default['AUTH_DISABLE_DEFAULT']) {
|
|
29
29
|
const defaultProvider = getProviderInstance('local', options);
|
|
30
30
|
providers.set(constants_1.DEFAULT_AUTH_PROVIDER, defaultProvider);
|
|
31
31
|
}
|
|
32
|
-
if (!env_1.default
|
|
32
|
+
if (!env_1.default['AUTH_PROVIDERS']) {
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
35
35
|
// Register configured providers
|
|
@@ -66,4 +66,5 @@ function getProviderInstance(driver, options, config = {}) {
|
|
|
66
66
|
case 'saml':
|
|
67
67
|
return new drivers_1.SAMLAuthDriver(options, config);
|
|
68
68
|
}
|
|
69
|
+
return undefined;
|
|
69
70
|
}
|
package/dist/cache.d.ts
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import Keyv from 'keyv';
|
|
2
|
+
import type { SchemaOverview } from '@directus/shared/types';
|
|
2
3
|
export declare function getCache(): {
|
|
3
4
|
cache: Keyv | null;
|
|
4
5
|
systemCache: Keyv;
|
|
6
|
+
sharedSchemaCache: Keyv;
|
|
7
|
+
localSchemaCache: Keyv;
|
|
5
8
|
lockCache: Keyv;
|
|
6
9
|
};
|
|
7
10
|
export declare function flushCaches(forced?: boolean): Promise<void>;
|
|
8
|
-
export declare function clearSystemCache(
|
|
11
|
+
export declare function clearSystemCache(opts?: {
|
|
12
|
+
forced?: boolean | undefined;
|
|
13
|
+
autoPurgeCache?: false | undefined;
|
|
14
|
+
}): Promise<void>;
|
|
9
15
|
export declare function setSystemCache(key: string, value: any, ttl?: number): Promise<void>;
|
|
10
16
|
export declare function getSystemCache(key: string): Promise<Record<string, any>>;
|
|
17
|
+
export declare function setSchemaCache(schema: SchemaOverview): Promise<void>;
|
|
18
|
+
export declare function getSchemaCache(): Promise<SchemaOverview | undefined>;
|
|
11
19
|
export declare function setCacheValue(cache: Keyv, key: string, value: Record<string, any> | Record<string, any>[], ttl?: number): Promise<void>;
|
|
12
20
|
export declare function getCacheValue(cache: Keyv, key: string): Promise<any>;
|