From 87fba04052b6d720896b594665a28dd4085a70fc Mon Sep 17 00:00:00 2001 From: Matthieu Sieben Date: Thu, 20 Feb 2025 13:20:50 +0100 Subject: [PATCH 01/90] Add support for reset password --- .changeset/brave-countries-return.md | 5 + .changeset/eleven-ducks-boil.md | 5 + .changeset/hungry-buttons-clean.md | 5 + .changeset/short-masks-punch.md | 5 + .changeset/tall-rules-hammer.md | 5 + .changeset/tiny-goats-sing.md | 5 + .changeset/tiny-hornets-love.md | 5 + .vscode/settings.json | 1 + package.json | 2 +- packages/dev-env/src/pds.ts | 10 +- packages/internal/fetch/package.json | 3 - packages/internal/fetch/src/fetch-response.ts | 36 +- packages/internal/fetch/src/util.ts | 18 - .../src/index.ts | 21 +- .../oauth-client-browser-example/package.json | 8 +- .../oauth-client-browser-example/src/app.tsx | 6 +- .../src/auth/auth-form.tsx | 15 +- .../src/auth/auth-provider.tsx | 28 +- .../src/auth/oauth/oauth-sign-in-form.tsx | 91 +- .../src/auth/oauth/use-oauth.ts | 2 +- .../src/constants.ts | 4 + .../oauth-client-browser-example/src/main.tsx | 20 +- .../tailwind.config.js | 2 + .../oauth-client/src/oauth-response-error.ts | 8 +- packages/oauth/oauth-client/src/util.ts | 2 + packages/oauth/oauth-provider/.gitignore | 2 + packages/oauth/oauth-provider/.linguirc | 56 + packages/oauth/oauth-provider/package.json | 30 +- .../oauth/oauth-provider/rollup.config.js | 130 +- .../src/account/account-manager.ts | 164 +- .../src/account/account-store.ts | 133 +- .../src/account/sign-in-data.ts | 15 + .../src/account/sign-up-data.ts | 11 + .../oauth-provider/src/assets/app/app.tsx | 43 +- .../src/assets/app/backend-data.ts | 65 +- .../src/assets/app/backend-types.ts | 61 + .../src/assets/app/components/accept-form.tsx | 137 -- .../app/components/account-identifier.tsx | 18 - .../assets/app/components/account-picker.tsx | 127 -- .../src/assets/app/components/button.tsx | 34 - .../src/assets/app/components/client-name.tsx | 37 - .../src/assets/app/components/fieldset.tsx | 26 - .../src/assets/app/components/form-card.tsx | 47 - .../forms/button-toggle-visibility.tsx | 41 + .../assets/app/components/forms/button.tsx | 60 + .../assets/app/components/forms/fieldset.tsx | 55 + .../app/components/forms/form-card-async.tsx | 100 + .../assets/app/components/forms/form-card.tsx | 49 + .../app/components/forms/input-checkbox.tsx | 69 + .../app/components/forms/input-container.tsx | 45 + .../components/forms/input-email-address.tsx | 66 + .../app/components/forms/input-info-card.tsx | 47 + .../app/components/forms/input-layout.tsx | 57 + .../components/forms/input-new-password.tsx | 76 + .../app/components/forms/input-password.tsx | 91 + .../app/components/{ => forms}/input-text.tsx | 60 +- .../app/components/forms/input-token.tsx | 94 + .../app/components/forms/wizard-card.tsx | 104 + .../src/assets/app/components/help-card.tsx | 42 - .../app/components/icons/alert-icon.tsx | 5 - .../app/components/icons/at-symbol-icon.tsx | 5 - .../app/components/icons/caret-right-icon.tsx | 5 - .../assets/app/components/icons/lock-icon.tsx | 5 - .../app/components/icons/token-icon.tsx | 5 - .../src/assets/app/components/icons/util.tsx | 17 - .../src/assets/app/components/info-card.tsx | 45 - .../assets/app/components/input-checkbox.tsx | 47 - .../assets/app/components/input-container.tsx | 37 - .../assets/app/components/input-layout.tsx | 47 - .../{ => layouts}/layout-title-page.tsx | 15 +- .../{ => layouts}/layout-welcome.tsx | 39 +- .../assets/app/components/sign-in-form.tsx | 337 --- .../app/components/sign-up-account-form.tsx | 194 -- .../app/components/sign-up-disclaimer.tsx | 44 - .../components/utils/account-identifier.tsx | 23 + .../app/components/utils/client-name.tsx | 45 + .../app/components/utils/error-card.tsx | 68 + .../app/components/utils/error-message.tsx | 57 + .../components/utils/expand-transition.tsx | 35 + .../assets/app/components/utils/help-card.tsx | 47 + .../src/assets/app/components/utils/icons.tsx | 88 + .../utils/password-strength-label.tsx | 34 + .../utils/password-strength-meter.tsx | 65 + .../app/components/{ => utils}/url-viewer.tsx | 15 +- .../src/assets/app/hooks/use-api.ts | 164 +- .../src/assets/app/hooks/use-async-action.ts | 120 ++ .../app/hooks/use-browser-color-scheme.ts | 28 + .../src/assets/app/hooks/use-csrf-token.ts | 2 +- .../src/assets/app/hooks/use-random-string.ts | 37 + .../src/assets/app/hooks/use-stepper.ts | 72 + .../oauth-provider/src/assets/app/lib/api.ts | 312 ++- .../src/assets/app/lib/json-client.ts | 96 + .../src/assets/app/lib/password.ts | 79 + .../oauth-provider/src/assets/app/lib/ref.ts | 18 + .../src/assets/app/locales/an/messages.po | 427 ++++ .../src/assets/app/locales/ast/messages.po | 427 ++++ .../src/assets/app/locales/ca/messages.po | 427 ++++ .../src/assets/app/locales/da/messages.po | 427 ++++ .../src/assets/app/locales/de/messages.po | 427 ++++ .../src/assets/app/locales/el/messages.po | 427 ++++ .../src/assets/app/locales/en-GB/messages.po | 427 ++++ .../src/assets/app/locales/en/messages.po | 427 ++++ .../src/assets/app/locales/es/messages.po | 427 ++++ .../src/assets/app/locales/eu/messages.po | 427 ++++ .../src/assets/app/locales/fi/messages.po | 427 ++++ .../src/assets/app/locales/fr/messages.po | 427 ++++ .../src/assets/app/locales/ga/messages.po | 427 ++++ .../src/assets/app/locales/gl/messages.po | 427 ++++ .../src/assets/app/locales/hi/messages.po | 427 ++++ .../src/assets/app/locales/hu/messages.po | 427 ++++ .../src/assets/app/locales/ia/messages.po | 427 ++++ .../src/assets/app/locales/id/messages.po | 427 ++++ .../src/assets/app/locales/index.ts | 41 + .../src/assets/app/locales/it/messages.po | 427 ++++ .../src/assets/app/locales/ja/messages.po | 427 ++++ .../src/assets/app/locales/km/messages.po | 427 ++++ .../src/assets/app/locales/ko/messages.po | 427 ++++ .../src/assets/app/locales/ne/messages.po | 427 ++++ .../src/assets/app/locales/nl/messages.po | 427 ++++ .../src/assets/app/locales/pl/messages.po | 427 ++++ .../src/assets/app/locales/pt-BR/messages.po | 427 ++++ .../src/assets/app/locales/ro/messages.po | 427 ++++ .../src/assets/app/locales/ru/messages.po | 427 ++++ .../src/assets/app/locales/sv/messages.po | 427 ++++ .../src/assets/app/locales/th/messages.po | 427 ++++ .../src/assets/app/locales/tr/messages.po | 427 ++++ .../src/assets/app/locales/uk/messages.po | 427 ++++ .../src/assets/app/locales/vi/messages.po | 427 ++++ .../src/assets/app/locales/zh-CN/messages.po | 427 ++++ .../src/assets/app/locales/zh-HK/messages.po | 427 ++++ .../src/assets/app/locales/zh-TW/messages.po | 427 ++++ .../oauth-provider/src/assets/app/main.css | 7 +- .../oauth-provider/src/assets/app/main.tsx | 24 +- .../src/assets/app/views/accept-view.tsx | 55 - .../src/assets/app/views/authorize-view.tsx | 106 - .../views/authorize/accept/accept-form.tsx | 146 ++ .../views/authorize/accept/accept-view.tsx | 64 + .../app/views/authorize/authorize-view.tsx | 179 ++ .../reset-password-confirm-form.tsx | 85 + .../reset-password-request-form.tsx | 77 + .../reset-password/reset-password-view.tsx | 124 ++ .../views/authorize/sign-in/sign-in-form.tsx | 248 +++ .../authorize/sign-in/sign-in-picker.tsx | 142 ++ .../views/authorize/sign-in/sign-in-view.tsx | 142 ++ .../sign-up/sign-up-account-form.tsx | 166 ++ .../authorize/sign-up/sign-up-disclaimer.tsx | 53 + .../authorize/sign-up/sign-up-handle-form.tsx | 271 +++ .../sign-up/sign-up-hcaptcha-form.tsx | 99 + .../views/authorize/sign-up/sign-up-view.tsx | 145 ++ .../{ => authorize/welcome}/welcome-view.tsx | 40 +- .../src/assets/app/views/error-view.tsx | 36 - .../src/assets/app/views/error/error-view.tsx | 44 + .../src/assets/app/views/sign-in-view.tsx | 111 - .../src/assets/app/views/sign-up-view.tsx | 86 - .../src/assets/assets-middleware.ts | 4 +- .../src/device/device-manager.ts | 20 +- .../src/errors/handle-unavailable-error.ts | 18 + .../src/errors/invalid-request-error.ts | 18 +- .../oauth/oauth-provider/src/lib/csp/index.ts | 98 + .../oauth/oauth-provider/src/lib/hcaptcha.ts | 183 ++ .../oauth-provider/src/lib/http/middleware.ts | 7 +- .../oauth-provider/src/lib/http/request.ts | 16 +- .../oauth-provider/src/lib/http/response.ts | 31 +- .../oauth-provider/src/lib/util/function.ts | 3 - .../oauth/oauth-provider/src/lib/util/type.ts | 8 +- .../src/metadata/build-metadata.ts | 3 +- .../oauth/oauth-provider/src/oauth-errors.ts | 1 + .../oauth/oauth-provider/src/oauth-hooks.ts | 72 +- .../oauth-provider/src/oauth-provider.ts | 644 +++--- .../src/output/build-authorize-data.ts | 4 +- ...ization.ts => build-customization-data.ts} | 106 +- .../src/output/output-manager.ts | 26 +- .../src/output/send-authorize-redirect.ts | 79 +- .../src/output/send-web-page.ts | 59 +- .../src/request/request-manager.ts | 8 +- .../oauth/oauth-provider/tailwind.config.js | 5 + .../oauth-provider/tsconfig.frontend.json | 3 +- .../{index.ts => account-manager.ts} | 414 +--- .../account-manager/helpers/device-account.ts | 1 + .../pds/src/account-manager/oauth-store.ts | 485 +++++ .../api/com/atproto/admin/deleteAccount.ts | 2 +- .../com/atproto/admin/updateAccountHandle.ts | 14 +- .../api/com/atproto/identity/resolveHandle.ts | 13 +- .../api/com/atproto/identity/updateHandle.ts | 10 +- .../api/com/atproto/server/createAccount.ts | 18 +- .../api/com/atproto/server/createSession.ts | 2 +- .../api/com/atproto/server/deleteAccount.ts | 2 +- .../src/api/com/atproto/server/getSession.ts | 2 +- .../api/com/atproto/server/refreshSession.ts | 2 +- .../src/api/com/atproto/sync/getRepoStatus.ts | 2 +- .../pds/src/api/com/atproto/sync/listRepos.ts | 2 +- packages/pds/src/app-view.ts | 24 + packages/pds/src/auth-routes.ts | 12 +- packages/pds/src/auth-verifier.ts | 2 +- packages/pds/src/config/config.ts | 18 +- packages/pds/src/config/env.ts | 12 + packages/pds/src/context.ts | 68 +- packages/pds/src/handle/index.ts | 58 +- packages/pds/src/image/image-url.ts | 16 + packages/pds/src/oauth/provider.ts | 59 - packages/pds/src/read-after-write/viewer.ts | 2 +- packages/pds/src/sequencer/events.ts | 2 +- packages/syntax/src/handle.ts | 3 + pnpm-lock.yaml | 1883 ++++++++++++++--- 204 files changed, 23822 insertions(+), 3341 deletions(-) create mode 100644 .changeset/brave-countries-return.md create mode 100644 .changeset/eleven-ducks-boil.md create mode 100644 .changeset/hungry-buttons-clean.md create mode 100644 .changeset/short-masks-punch.md create mode 100644 .changeset/tall-rules-hammer.md create mode 100644 .changeset/tiny-goats-sing.md create mode 100644 .changeset/tiny-hornets-love.md create mode 100644 packages/oauth/oauth-provider/.gitignore create mode 100644 packages/oauth/oauth-provider/.linguirc create mode 100644 packages/oauth/oauth-provider/src/account/sign-in-data.ts create mode 100644 packages/oauth/oauth-provider/src/account/sign-up-data.ts create mode 100644 packages/oauth/oauth-provider/src/assets/app/backend-types.ts delete mode 100644 packages/oauth/oauth-provider/src/assets/app/components/accept-form.tsx delete mode 100644 packages/oauth/oauth-provider/src/assets/app/components/account-identifier.tsx delete mode 100644 packages/oauth/oauth-provider/src/assets/app/components/account-picker.tsx delete mode 100644 packages/oauth/oauth-provider/src/assets/app/components/button.tsx delete mode 100644 packages/oauth/oauth-provider/src/assets/app/components/client-name.tsx delete mode 100644 packages/oauth/oauth-provider/src/assets/app/components/fieldset.tsx delete mode 100644 packages/oauth/oauth-provider/src/assets/app/components/form-card.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/forms/button-toggle-visibility.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/forms/button.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/forms/fieldset.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/forms/form-card-async.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/forms/form-card.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/forms/input-checkbox.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/forms/input-container.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/forms/input-email-address.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/forms/input-info-card.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/forms/input-layout.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/forms/input-new-password.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/forms/input-password.tsx rename packages/oauth/oauth-provider/src/assets/app/components/{ => forms}/input-text.tsx (52%) create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/forms/input-token.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/forms/wizard-card.tsx delete mode 100644 packages/oauth/oauth-provider/src/assets/app/components/help-card.tsx delete mode 100644 packages/oauth/oauth-provider/src/assets/app/components/icons/alert-icon.tsx delete mode 100644 packages/oauth/oauth-provider/src/assets/app/components/icons/at-symbol-icon.tsx delete mode 100644 packages/oauth/oauth-provider/src/assets/app/components/icons/caret-right-icon.tsx delete mode 100644 packages/oauth/oauth-provider/src/assets/app/components/icons/lock-icon.tsx delete mode 100644 packages/oauth/oauth-provider/src/assets/app/components/icons/token-icon.tsx delete mode 100644 packages/oauth/oauth-provider/src/assets/app/components/icons/util.tsx delete mode 100644 packages/oauth/oauth-provider/src/assets/app/components/info-card.tsx delete mode 100644 packages/oauth/oauth-provider/src/assets/app/components/input-checkbox.tsx delete mode 100644 packages/oauth/oauth-provider/src/assets/app/components/input-container.tsx delete mode 100644 packages/oauth/oauth-provider/src/assets/app/components/input-layout.tsx rename packages/oauth/oauth-provider/src/assets/app/components/{ => layouts}/layout-title-page.tsx (79%) rename packages/oauth/oauth-provider/src/assets/app/components/{ => layouts}/layout-welcome.tsx (71%) delete mode 100644 packages/oauth/oauth-provider/src/assets/app/components/sign-in-form.tsx delete mode 100644 packages/oauth/oauth-provider/src/assets/app/components/sign-up-account-form.tsx delete mode 100644 packages/oauth/oauth-provider/src/assets/app/components/sign-up-disclaimer.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/utils/account-identifier.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/utils/client-name.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/utils/error-card.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/utils/error-message.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/utils/expand-transition.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/utils/help-card.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/utils/icons.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/utils/password-strength-label.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/components/utils/password-strength-meter.tsx rename packages/oauth/oauth-provider/src/assets/app/components/{ => utils}/url-viewer.tsx (83%) create mode 100644 packages/oauth/oauth-provider/src/assets/app/hooks/use-async-action.ts create mode 100644 packages/oauth/oauth-provider/src/assets/app/hooks/use-browser-color-scheme.ts create mode 100644 packages/oauth/oauth-provider/src/assets/app/hooks/use-random-string.ts create mode 100644 packages/oauth/oauth-provider/src/assets/app/hooks/use-stepper.ts create mode 100644 packages/oauth/oauth-provider/src/assets/app/lib/json-client.ts create mode 100644 packages/oauth/oauth-provider/src/assets/app/lib/password.ts create mode 100644 packages/oauth/oauth-provider/src/assets/app/lib/ref.ts create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/an/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/ast/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/ca/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/da/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/de/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/el/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/en-GB/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/en/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/es/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/eu/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/fi/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/fr/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/ga/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/gl/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/hi/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/hu/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/ia/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/id/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/index.ts create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/it/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/ja/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/km/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/ko/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/ne/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/nl/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/pl/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/pt-BR/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/ro/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/ru/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/sv/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/th/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/tr/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/uk/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/vi/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/zh-CN/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/zh-HK/messages.po create mode 100644 packages/oauth/oauth-provider/src/assets/app/locales/zh-TW/messages.po delete mode 100644 packages/oauth/oauth-provider/src/assets/app/views/accept-view.tsx delete mode 100644 packages/oauth/oauth-provider/src/assets/app/views/authorize-view.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/views/authorize/accept/accept-form.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/views/authorize/accept/accept-view.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/views/authorize/authorize-view.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/views/authorize/reset-password/reset-password-confirm-form.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/views/authorize/reset-password/reset-password-request-form.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/views/authorize/reset-password/reset-password-view.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/views/authorize/sign-in/sign-in-form.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/views/authorize/sign-in/sign-in-picker.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/views/authorize/sign-in/sign-in-view.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/views/authorize/sign-up/sign-up-account-form.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/views/authorize/sign-up/sign-up-disclaimer.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/views/authorize/sign-up/sign-up-handle-form.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/views/authorize/sign-up/sign-up-hcaptcha-form.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/views/authorize/sign-up/sign-up-view.tsx rename packages/oauth/oauth-provider/src/assets/app/views/{ => authorize/welcome}/welcome-view.tsx (51%) delete mode 100644 packages/oauth/oauth-provider/src/assets/app/views/error-view.tsx create mode 100644 packages/oauth/oauth-provider/src/assets/app/views/error/error-view.tsx delete mode 100644 packages/oauth/oauth-provider/src/assets/app/views/sign-in-view.tsx delete mode 100644 packages/oauth/oauth-provider/src/assets/app/views/sign-up-view.tsx create mode 100644 packages/oauth/oauth-provider/src/errors/handle-unavailable-error.ts create mode 100644 packages/oauth/oauth-provider/src/lib/csp/index.ts create mode 100644 packages/oauth/oauth-provider/src/lib/hcaptcha.ts rename packages/oauth/oauth-provider/src/output/{customization.ts => build-customization-data.ts} (53%) rename packages/pds/src/account-manager/{index.ts => account-manager.ts} (59%) create mode 100644 packages/pds/src/account-manager/oauth-store.ts create mode 100644 packages/pds/src/app-view.ts create mode 100644 packages/pds/src/image/image-url.ts delete mode 100644 packages/pds/src/oauth/provider.ts diff --git a/.changeset/brave-countries-return.md b/.changeset/brave-countries-return.md new file mode 100644 index 00000000000..4ce768d1745 --- /dev/null +++ b/.changeset/brave-countries-return.md @@ -0,0 +1,5 @@ +--- +"@atproto/oauth-provider": patch +--- + +Add support for password reset diff --git a/.changeset/eleven-ducks-boil.md b/.changeset/eleven-ducks-boil.md new file mode 100644 index 00000000000..cdd84f0bac2 --- /dev/null +++ b/.changeset/eleven-ducks-boil.md @@ -0,0 +1,5 @@ +--- +"@atproto-labs/fetch": patch +--- + +Improved error response parsing diff --git a/.changeset/hungry-buttons-clean.md b/.changeset/hungry-buttons-clean.md new file mode 100644 index 00000000000..21869c2c6c6 --- /dev/null +++ b/.changeset/hungry-buttons-clean.md @@ -0,0 +1,5 @@ +--- +"@atproto/oauth-client-browser-example": patch +--- + +Update react to version 19 diff --git a/.changeset/short-masks-punch.md b/.changeset/short-masks-punch.md new file mode 100644 index 00000000000..950ecb51823 --- /dev/null +++ b/.changeset/short-masks-punch.md @@ -0,0 +1,5 @@ +--- +"@atproto/syntax": patch +--- + +Deprecate unused classes diff --git a/.changeset/tall-rules-hammer.md b/.changeset/tall-rules-hammer.md new file mode 100644 index 00000000000..9f70720c7e1 --- /dev/null +++ b/.changeset/tall-rules-hammer.md @@ -0,0 +1,5 @@ +--- +"@atproto/oauth-client": patch +--- + +Minor code optimizations diff --git a/.changeset/tiny-goats-sing.md b/.changeset/tiny-goats-sing.md new file mode 100644 index 00000000000..edbdb902999 --- /dev/null +++ b/.changeset/tiny-goats-sing.md @@ -0,0 +1,5 @@ +--- +"@atproto-labs/fetch": patch +--- + +Remove optional dependeny on "zod" diff --git a/.changeset/tiny-hornets-love.md b/.changeset/tiny-hornets-love.md new file mode 100644 index 00000000000..ec3e367b437 --- /dev/null +++ b/.changeset/tiny-hornets-love.md @@ -0,0 +1,5 @@ +--- +"@atproto-labs/rollup-plugin-bundle-manifest": patch +--- + +Remove unused fields from output manifest diff --git a/.vscode/settings.json b/.vscode/settings.json index 4f8e93dede2..2d95c43f7f0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,6 +12,7 @@ "consolas", "dpop", "googleusercontent", + "hcaptcha", "hexeditor", "ingester", "insertable", diff --git a/package.json b/package.json index 2601cf8493d..dccb05e1518 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "packageManager": "pnpm@8.15.9", "scripts": { "lint:fix": "pnpm lint --fix", - "lint": "eslint . --ext .ts,.js", + "lint": "eslint . --ext .ts,.js,.tsx,.jsx", "style:fix": "prettier --write .", "style": "prettier --check .", "verify": "pnpm --stream '/^verify:.+$/'", diff --git a/packages/dev-env/src/pds.ts b/packages/dev-env/src/pds.ts index d721a8797cd..5483ca19704 100644 --- a/packages/dev-env/src/pds.ts +++ b/packages/dev-env/src/pds.ts @@ -37,7 +37,7 @@ export class TestPds { recoveryDidKey: recoveryKey, adminPassword: ADMIN_PASSWORD, jwtSecret: JWT_SECRET, - serviceHandleDomains: ['.test'], + serviceHandleDomains: ['.test', '.example'], bskyAppViewUrl: 'https://appview.invalid', bskyAppViewDid: 'did:example:invalid', bskyAppViewCdnUrlPattern: 'http://cdn.appview.com/%s/%s/%s', @@ -47,10 +47,12 @@ export class TestPds { inviteRequired: false, disableSsrfProtection: true, serviceName: 'Development PDS', - brandColor: '#ffcb1e', - errorColor: undefined, + brandColor: '#8338ec', + errorColor: '#ff006e', + warningColor: '#fb5607', + successColor: '#02c39a', logoUrl: - 'https://uxwing.com/wp-content/themes/uxwing/download/animals-and-birds/bee-icon.png', + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAMAAADDpiTIAAAASFBMVEVHcEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIBgD/yx7xwBvesRnKoRe1kBSaexGCZw5pUwtOPgg2KwUeFwMAAACAAUqJAAAADHRSTlMAECM7VGyEm7XP5PowwePsAAAXmElEQVR42u3d13LkOJAF0KI3MCRs/v+f7k5PzFKrlooehnXPc0dUhwAmMhMg8cpa1fYDIzb2XV3E+OHhzw9DHFVHX/V1tB/GWERQ9vTdWEf64aHCeITW0Q/YUMT5YeqxEARVDPQzVkX64bHEqIRTjvSr+nWjitGvkAkEUzB6o7px4jF6A4lAKAO9Vd428UZ6h2EVCKOj98bidY+e3huQCYZQ0Zr2dYua1jQYnVALQIxFYKRVCAH3q2ld97pBQ+tajE/MALAo7gkACAHxlbRFfe8PoxkQT0Nb9LF+uMMI3awnihOKB9oEI3QzRougdQBtg2bQzYjirMUFLdAPjqeMNQFKImSBCahom/amH0YzMLIy1gSoMQGSUMQahwZLQBriRIB6ICSBSZeBtx4QrUf6A73gBHS0VV+FH34aMUI3q2m7rrz2FCi2AxNQ0B71VfMNKUAy+pBPZEf7MIzP7SrapS8uOX2OLkCuIYBYdTL8IwVMTEk7VedDDbpAKWlop+r8+OM0SEo62qm8ZvzxWkAqBtqHlZeM/1APeDEoCUVPvxnLalh5Wejg+A/Vvz+M14NT0L4Lw/V4cgYU46/fgOiI8IGAFNTsXd+nOZegdW8aSvWIBkCqxUBXvHmRvzrRABir99GnxeMfQ9H0tBia8u0mDisONRqWibUo6v//w1j9oynqpu2GvmvrcjWOd0drjO7NDzf4Sly6umN9uhbtnafojywCJcb/OYYDY9lh/HO1Xs+XuwPAgD9i1qrdj3OPV/0epd05nhX6O49OA7p9/7zH3+9px0fKPQGAocZ/gHZPCBiwADxOsePNnRIn/B6o3f5Utzjh90DF9sKeIQA8Ubs1DawRAB6p2PquUI8A8Ezttre3CpQAD1VuC+0NXvR/qmFTe29AE/Cpmi0f8yyQAj5WseV4aI33vJ+r31AHdPjSx3PVG3pBDOcAHmw9wS+xAjxZv5rgNTgJ+GTrw9ujBniyarXLiy7Qs61tCFXYB/jsJKBBEfg5SQD7YYA7fO7x2cqVRv+AFODhVtZ4pABPtv6Il9gJfLL1Rb7GWZCna94OcYs20NNVb3uBPXaCnq74a0OwLMvqH2VZvBiuf328kb4YRvoC3wTAZ+bRB8QnppdGITqBj1N1jHZgHebAg5TtSPt1qAY/dPQXHQrC3JUdnYKlIGtlT6f1mAK5qnq6xIBk4DOHfzFiCuSm6OhSPdLBrNSM1uBS0OcqelrlrTVGa6W0NsZaT6sGBIFn3DDvjJol/4uclXHYJHh46efNLPg7s7aMfjWiJMz58Xda8i1mw5AJPO5eYTsLvt1sGZaBJ235Gsl3EsrjhsiHZP9eC37E7HBHbFbKkX7gFD9ssvQfvDmWvIp+4BU/ZXJIBXMefyP4WcpjBuQ6/m7iFxAGMyDL8WeaX2Ty9A98SDJdJf3FSn4ZYTADklYy+k7zSymGGZCugtF3il9MOlSDyRroGz/xywlLRLhVLkUtfeMkv4PBS4R57P9Zwe+hsTOUQwFg+G0UEsHkFGOQ8V9mAG4XT3sD2PJbaaQBaanCjP9Coyec8gLgBL+bwSKQbgXoBb+fI8JHBROtACYegPCoBBJtASoexESEywVSbAEZHogiwv0yKRjDJgALizwwBU3gBGAhGEJAcgHA8IAUQkB8TfgFYOEQAhILADMPSiIEpBUALA9MIwRENsTIABeCoRcQVRknACw02oFRtXECwEIwbAvHxCIFgIVGGhhRHSsALATD8cBEbn9wPApDXzCMSUgFfaV4FBNeE0lkBRA8Do81IJYuYgq40KgDkmgDzzwSgV5QCl0gxqNx6AXF0URdARYa+wEJFIGKRzPh0vkE2oCSx8OQBETvAngekUUnIPr7YIZHpPCWWPQcUPGIJmSB0beCJx6RoAVDKyhKESB4TB77QZH7gJ5HZVEGRBB9K3hhUAZErgINj0phAkTeCdA8qhm7AZgAaATE7AMpHtWECRBendAEkDgUFHkCzJgAH6dJaAII9IIjT4AJEwBLAJYAVAGoAjABMAHQCEInEBMAewHYDMIEeLqEJoDGNwIiTwDLozI4EBIBS/RACEbmA4+EYQLgUCgOheJYOO4O+dDtwAlbAdF7wRqvhn2cMplGgEYfKP6LAXgv5PMMtPAoAlAHoghAHYgiAAfD8VrIZ9aBFq+G4iNBkXgUAZEMSXwmTOJz4bF0SSQBCi8FxFIn0Qu0OBGaRhKAFODDPxcu8aHYj9MmkARotIFSSQLwnVgkAbguAneGBDZjJ+izbw0y2AhIJglgggcncGncZ98cqNEH/uy7Qz36wHFVcW8PnnF7fGwsaivAYgWIrY3ZCpCENmBsJR1vBQgh5TTN/5ik4PsZdIHiG/aHADkrYz19x7yz1qhJ8I0EUsAE1HsqwUlp62mNt3qWfJ1CEyC5VoAX/DdSWUbbMWfmtQCAe8NT0NF6ISCU8bSft0q8ywDQBk5BRSt54GQcHeeU5D+aCClggt1AYvLbs+/oLK8l/5tDDZiIin5NAybD6BJ2/mEBwMfhkswCyMnl4b+OU993gXASIK1CYOGVWB7+63gtvlSACAAJaeg75+kORv7f848MICHFSKHYWU7KERFOg6ekotCwD5yWhnZizhpjtFZqnudpVtpY5z1thAwwOd2eHu/vrX4xzdoy2mVEDygFA21hZsnXTcp6+h0qgGwTQSb4VnI2DgnA0xJBc/jM7wIVYGrKqm67gbaQfBdJG7Cha+sKeUCUkW/afqTt7MFDn5gHiSnrputH2m3mO02029C3DebBXYqqXp753TzfzdFBQ9fUKA8ufugHRqcovpuiU0aEg/M2PvTna8D1c38IB+Gf+pEuY/gBmi4zdIgGWxVV0w10MckPkHStsW8RDN4ql4h/LXv69T8Eg/vHfqDbzPyQme7C+rbGLFhifs/oTp4f5OhOY9dUePC7gW6n+EGKbjd8bF5QVG3PKAQm+EGCUQisb6ri0x78kYIx/DBDwYxd8xmhoKjbkYKS/DBJQY3d01PDqukpNMtPsBTa0FaPffQ7RhHM/ISZYuiftxpU7UhxeH6KozjYk1aDqqN4FD9FUTz9I+ZAtRL4k60Bl0oQc+CwqmUUl7nik9CYA4eU7UjRySs+CIg5sF/RjpQAy0+zlIK+ziv095SGmZ82UxpYm0sYKJqREuH5BTyloq9e6Ss7SofiF1CUjrFJPAzUPSWECX4BwSglXZVw4scoKYZfwlBahjrR4afUSH4JSakZGwz/BpZfxBKmQC7Df8ttgjMliDUY/vc8v4yj9LBUpkDRUJoUv4wiwhT4RcMoTUzwywhPiWL1K6pqpFQZfiFNyRqqiNG/o3RJfiFJCeuKWNGfEmZvuiYQBcF/qoFSNvNLTUREWAfSLv1uvUzYERHWgf9TM0qb4hdTlLoGyd/CC341T2lj1IcKAuVIqdP8cpqSxyok/0sNeDVBGWgDhP+e0mf5DQxlYChf96oYZWDiN5goC3WAO/tT5/gtHGWhLyKH//gUv8VMeRjLqNl/fJ7fxFMmqnvGn1EeNL+JosXnJQIV5ULwmwhGi0+rB2vKheG3MZSNLlj35/k14EJSPoYiyt188Vl+I0v5GMuPHH+a+Y1m+sgZ0FI+PL+Vo4yMRazxj98EQiV43QxoKCNM8FsJTzkZiovqP9SA/9H0YTOgpqxIvokQcprmWSmt/r1FfpJSPKgSXPQB+n/Z1IBimrWx3tNvvLNGzZPgb5iPmgElLTJuAk2zMtYx2mKZCCL2sYD4PcFipKy4n++CZ3SMN2qKWQnG3xnqKC/q29hr6+ksZ5TMshm0KIMXgPGbQNMy9hdgVk/BjwXEbweUlBnN/xDKeLqcN7NYKsG89I9PAJYacNKObmOVDHZAPP7xgJ4yY4Synm7m9MQNZad6bgKwYBSGt5Sf4rVTQRBR/G5Ah79ZRPEXgQp/sYcZX7uM9FTeOWuN0Vr92QP6b1NIa2Os9fRcbdwMMD7mrFaT4O/JWZmHzoPyYzPAPyMv+UbLPGD0KMNHZoBWz4Lvc7ahnP+uUEmP4K2e+GlSPWYSjB8UALxRkl9GKuM/KASUlDmrJL+c1I5yN35AAGB2Fvwmk/afEAKKnAP/zP+FOXA8BLQY/bemnPOB+qkBwOuJhzMZytTw0CagkzysyT12T2igP/A+0ApDWeqeWANqHsPEKEebVwB8EmLN/Mg0cKTceMF/gRdFf9BtWwHwSZAtDD3udGCLBGAPR/mpn7UCOP4evhfxXb9lBcBH4TZSD6sDanQAdrLP6gV1RIRPAu0hKTvNShsQ3wTb6IGvihbIAPdzD0oCKmSA+00POh/eoAd8gH1OEtAjABwgn9MNHlECHmEecyqEsiL5TrhJ5F/s9YsCAeAY/ZAyoEQP6Bjhn1EG1NgFPEg9oxlc4xjIUf4RO8ItAsBR6hHfiugQAA7zT2gEdAgAhylMgNABACHg+gmAAHCcwgQIGwAQAm6YAAgAJyhMgBgBAO3AC88EdQgAZyhEgHABACHgjgnQIgCconPvBDYIAKcIn/mZsBoB4Byd+WZQhQBwjvB5bwcXCAAnqczPhSMAnOXzfjOE4WWwk+YcD4UuerwMdpbL+uXAFt+DOWvO+vKYGgHgNJvzR2IKvAx22pT15UEj3gY9zeSXAy76J78MJqdpVloba53/yjlrtFbzJAW/gMz5K1FN3i+Dnb8Kzjuj50k8OgS02V4YKvheUmnrGO2xzAP50HdFq9cbjNKlQ9/5xg7eOaeySwEW3SNKQDFrd+H9Y9OjFoEu00ujmeTbzMbR1Zye+B423ysjMt8EmI2nezCjBN9KOEpWpnfGmQPXOUUMBNLnemVInesu8GR8SneTTSzTCyOKLHvAQnsKxpsp310h9lrT5lcBSkOBeS0zPSDYvtaUufWAJ0sxWCVyLAXK16qeksP4r5SjvZh3zv7HWec8o0NWlgKV6j5Afmmgv2Dp99b82fCRv2wUzbPSZm/f2M2ZTYDqtcGYywRQbHtfX+zYOdLW0VZeiYwmwPjaosljAsyOVjk9i6M7iNqyjQmhyGYCNK8tCpbBBJB2NeTriZ8klXG0gZF5TIDxtU2T/AQQei1Fl/wqk7a0yogc6sD6tdGY+ASY/VqBdi2xvsXAtEg+AgyvreqkJ8Dkwo3+Qiq7lg6mHgGq12ZDwhNAhx/9JRCwHUWhzq4HsKiSnQDC/h6EJb+deB8HrEx4ApSvHfpEJ8Dk39TjYQjltu1a6HR3AdaVaU4AtRJ8A5FvOpBuSnMCjMVrlybBCSDsSk8+oNmtBgGdXgaY6yLg34V/K3lQ67uQTqZ3NLR97VWmNgHUSsQNT5q3QcAk1wPMaRFo+m/bwWal9o5CaP97EDD5LgDxF4H61dGCcWFXGrCxCM3oJ2zmhr7oIm8CHVGMMZvWHX0h3Er0j0gY+pE29EXRxj8JnE8aUH8/m+h/fMRSIS2tinnYcngdVVMU9YYUxEmekMnRiohJFStfh7Vxxn99AhiemNmvn8ZuIieAeSSCrFqPPmzmyRFmvQxr4jxPZxQDhTWW68uPkzxFs19dhqsoBUBOM6Av1jckDU+UMKt5WDmGH/+cZkC3VoIs4T+rIMD65c8Zc/xTbwc06zWon3jKhF2d2X3Y8c9oBozV+luqXvLEqdW9mDbkDlAmM2BZ/hd5jf9iZmuPYsXyeP4XRR/hf7uS/qdL+rVarOgD1//ntaHC/4LRd07wLAi7OhhNiHr6Ug3dqStefxmzG/+FWX0aqzHsgnpeFebxXwwr639WM6AMHFS71/XKge7RbupCs4nzfGdAGfIPSqx+LVJPBIZy2zbEzHnGM6BYWVcTDf/3L1xjvXG6KZ4bRoshZHlVv+5TdHQl1mxNOzXPjdj2VlbV07X6JaImHwTat6GqzjsATJu/0D4EiKhXathlpd9bZd4RYN7ek6vH6yJqCEVLp7G2eK2hLwzPjd7TlKuHiyJqIGVHpwz13s9UOJ4bs+/F3Kq7JqLmMAX6av9HCjzPjaUvNgXWZqTDxibM8J///w7b/6cdfcFz4w+8mFV3dEhfv6Ko+t2jXx7dfpA8MytV4HVzYGzLVzRF3dNW/TL629Q5NwLl8c581Y27HqnY6o7RmqGtTm4/qbyrwJ3KuhtoDeub4pWGsm57Rj8b+7Y6GF5yrgP16eZsUbX98PsftS5eiSnrpu36YaR/sHEchq6pTwUo+sLmXQUeVlR12/V9PwzDOI5917ZNXRWv3D2/DnT0xQsO6egLkW8RMGIoLzh/MOe7FdRhKFc8bz9Q0RcNhvKY6o4yQPx7h7wx1ro/rLXGaK3VJG/KASsM5QV1oOPniFlp4zy95Z01Wk0X54AFhvKg8ZrdADnvvUjcGTWLq86DMQzkJWWAPHrnB6NjvNWzuKAR3GMgL3kbRd1wzcNdtw7N9EWLgbwiC2Rm5+A7uorT85kcsMZAHnYsCxTKhbsodD0HLDGOlzSDSey70iHiHBCERvANvcBpx+jHnQMzcsCL1LuOhs+W7uc2zAGNPuBFyu07wlJ7CoOZib/n0Ae8CqOF3/jwxw8DSAEu029JAsShh5957/6X955dHAYmpAAhW0GToc3Yn17/LIX4NoWEnGalrfNXhAGNNlC4DcHJbu7rqknwdXJSxhGduTjcIgW4Dn3h9w7/0tOXfJ9p4x4C+2EKCIYU4KZW0LR7+L1R4sx1wYxWGfmuCzBgCC/cENQbbu5bMKsnftak3d4pYJAC3NUKctvv6PB6Dnh5vJ34wiMFuFBBX4ltt/R4M/FrTdpvjQKScBroSsPfR4OFfj/6M7/D9DYOLHfYKXQBLtX8VQgqT79bRj/sHFgqAouNgPu2A/yS+4W/Q3695+wV54JwFuDGk6Hv/v525iHId2HAzSgC43yflBnJA1g/ccRQBN7WDY4T+/duQKAIvBpbH/6Ebo0mvBFwtS728O/ahcZboZer14c/oSmAA+GXK5Ib/oX43pRAG/AGfarDz//uS6ENeIOGfqQFT4LQDCtA+DXASr5I5tJgHAe9xUDf+ZknRVrUAAHXAKZ5cmaHLtBtypVDWGlQnvBtsBBrgOWJEtgHCLMGSJ6mGTvBYeoAw9PksBMcZj+ACZ6iiXAWKNCesOYpsmgDhzoX5HmCJNrAd2qSv0jYoAkQLg10KdaASAEDbglOPDUa+0Ah00DLU+OxD3SzIelmkCJ0AW9WJ90McugC3o4l3AyaUAOGrgQVT4lFDRi6EvQ8IRM2gkNokw0BFjVgCCUlmgXMCABh9IkWAh4BIIySkuwFKASAUPoU24ECASBWCJh5CgwCQDhdepuCEq8DxQsBisdnEQDihQAveGwTAkBQBSV2OtAhAITVplUKKrwOFjcE2NglILYBQ2soocNhhnAOILgxnTxwJhwEiv7hQJPMAsDwMkgYXSr9QIMSMIU80Mt4CwDeBYiiSaISEB4lYCxjCh1hi08CpZIHkozfAhqRAUbsBzoenGRYAGIaY+8JOLQAoiopbi1oCJtAcTUUsyWsCT3g2PqI3YCZCB8ESm0RcIKHMjG0gBJQU6R+kPBYAJLQUZxtIYcFIA3FSDE6ggb3QqSiogjFoCa0AJOtBdkUYPyRACScBrCZ30vjVoC09GFXAU1IANNSDCFngMa1MMkpGQWrBQwuhktQRaFmgCEUACmqA80AQygAki0G7+8JCovL4TO6X9xJfq3JEwqAdHV33yypCOOf2QwgzS8jDC4GTl1Lf7GCX0M6jH+WM8BP/Aqzx/jnesm8FpeEf+T/2c4Ar/g5imH8s1HTD9zEj5scYfxznQHnLxuXhjD+eakY/YDp66I/jej/ZrM7vPBa8n2k9vSTDvs/WZWDCzvz7WZL/0D77wHLwMJvLAqFckSE8P+cZWBhleTvSWUY/aJH+M92GVh48+skEMp4IiKE/2cuAwtv1TxJsYy8nGZlPL3DUP3lpOhoA++ctc7TBi3Cf2aqga7TI/vLUD3SNUbs/WWqoc2Q/H1sKrBA6++Byp7O6JH7Z69sGR3DWuR+z1D3tF+P1O+TwwAe/k8OA32NzO+RyqYbaUXfIO97tLL+dRKwrkHg/whFVdVN2/XDyIjGoe/apqmrzxz8/wHrhW+8/D1ruwAAAABJRU5ErkJggg==', homeUrl: 'https://bsky.social/', termsOfServiceUrl: 'https://bsky.social/about/support/tos', privacyPolicyUrl: 'https://bsky.social/about/support/privacy-policy', diff --git a/packages/internal/fetch/package.json b/packages/internal/fetch/package.json index 4c5b913a303..fbf6beb054a 100644 --- a/packages/internal/fetch/package.json +++ b/packages/internal/fetch/package.json @@ -28,9 +28,6 @@ "devDependencies": { "typescript": "^5.6.3" }, - "optionalDependencies": { - "zod": "^3.23.8" - }, "scripts": { "build": "tsc --build tsconfig.json" } diff --git a/packages/internal/fetch/src/fetch-response.ts b/packages/internal/fetch/src/fetch-response.ts index 09e903bfefd..b4d83bc1caf 100644 --- a/packages/internal/fetch/src/fetch-response.ts +++ b/packages/internal/fetch/src/fetch-response.ts @@ -1,4 +1,3 @@ -import type { ParseParams, TypeOf, ZodTypeAny } from 'zod' import { Transformer, pipe } from '@atproto-labs/pipe' import { FetchError } from './fetch-error.js' import { TransformedResponse } from './transformed-response.js' @@ -6,7 +5,6 @@ import { Json, MaxBytesTransformStream, cancelBody, - ifObject, ifString, logCancellationError, } from './util.js' @@ -69,15 +67,16 @@ const extractResponseMessage: ResponseMessageGetter = async (response) => { const json: unknown = await response.json() if (typeof json === 'string') return json + if (typeof json === 'object' && json != null) { + const errorDescription = ifString(json['error_description']) + if (errorDescription) return errorDescription - const errorDescription = ifString(ifObject(json)?.['error_description']) - if (errorDescription) return errorDescription + const error = ifString(json['error']) + if (error) return error - const error = ifString(ifObject(json)?.['error']) - if (error) return error - - const message = ifString(ifObject(json)?.['message']) - if (message) return message + const message = ifString(json['message']) + if (message) return message + } } } catch { // noop @@ -283,10 +282,19 @@ export function fetchJsonProcessor( ) } -export function fetchJsonZodProcessor( - schema: S, - params?: Partial, -): Transformer> { - return async (jsonResponse: ParsedJsonResponse): Promise> => +// We are not using actual types imported from "zod" here to avoid +// compatibility issues with different versions of the library. + +type ParseParams = { + path?: (string | number)[] +} + +export function fetchJsonZodProcessor( + schema: { + parseAsync(value: unknown, params?: ParseParams): PromiseLike + }, + params?: ParseParams, +): Transformer { + return async (jsonResponse: ParsedJsonResponse): Promise => schema.parseAsync(jsonResponse.json, params) } diff --git a/packages/internal/fetch/src/util.ts b/packages/internal/fetch/src/util.ts index 67d5a81e28f..00b64d0e328 100644 --- a/packages/internal/fetch/src/util.ts +++ b/packages/internal/fetch/src/util.ts @@ -24,24 +24,6 @@ export function isIp(hostname: string) { return false } -const plainObjectProto = Object.prototype -export const ifObject = (v: V) => { - if (typeof v === 'object' && v != null && !Array.isArray(v)) { - const proto = Object.getPrototypeOf(v) - if (proto === null || proto === plainObjectProto) { - // eslint-disable-next-line @typescript-eslint/ban-types - return v as V extends JsonScalar | JsonArray | Function | symbol - ? never - : V extends Json - ? V - : // Plain object are (mostly) safe to access using a string index - Record - } - } - - return undefined -} - export const ifString = (v: V) => (typeof v === 'string' ? v : undefined) export class MaxBytesTransformStream extends TransformStream< diff --git a/packages/internal/rollup-plugin-bundle-manifest/src/index.ts b/packages/internal/rollup-plugin-bundle-manifest/src/index.ts index dae083970d2..73ad617ee22 100644 --- a/packages/internal/rollup-plugin-bundle-manifest/src/index.ts +++ b/packages/internal/rollup-plugin-bundle-manifest/src/index.ts @@ -14,11 +14,11 @@ type ChunkItem = { type: 'chunk' mime: string sha256: string - dynamicImports: string[] - isDynamicEntry: boolean - isEntry: boolean - isImplicitEntry: boolean - name: string + // dynamicImports: string[] + // isDynamicEntry: boolean + // isEntry: boolean + // isImplicitEntry: boolean + // name: string data?: string } @@ -32,7 +32,7 @@ export default function bundleManifest({ }: { name?: string data?: boolean -} = {}): Plugin { +} = {}): Plugin { return { name: 'bundle-manifest', generateBundle(outputOptions, bundle) { @@ -48,19 +48,12 @@ export default function bundleManifest({ mime: mime.getType(extname(fileName)) || undefined, sha256: createHash('sha256').update(chunk.source).digest('base64'), } - } - - if (chunk.type === 'chunk') { + } else if (chunk.type === 'chunk') { manifest[fileName] = { type: chunk.type, data: data ? Buffer.from(chunk.code).toString('base64') : undefined, mime: 'application/javascript', sha256: createHash('sha256').update(chunk.code).digest('base64'), - dynamicImports: chunk.dynamicImports, - isDynamicEntry: chunk.isDynamicEntry, - isEntry: chunk.isEntry, - isImplicitEntry: chunk.isImplicitEntry, - name: chunk.name, } } } diff --git a/packages/oauth/oauth-client-browser-example/package.json b/packages/oauth/oauth-client-browser-example/package.json index ba383a705fa..e4729b92507 100644 --- a/packages/oauth/oauth-client-browser-example/package.json +++ b/packages/oauth/oauth-client-browser-example/package.json @@ -41,12 +41,12 @@ "@rollup/plugin-replace": "^5.0.5", "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.6", - "@types/react": "^18.2.50", - "@types/react-dom": "^18.2.18", + "@types/react": "^19.0.10", + "@types/react-dom": "^19.0.4", "autoprefixer": "^10.4.17", "postcss": "^8.4.33", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", "rollup": "^4.13.0", "rollup-plugin-postcss": "^4.0.2", "rollup-plugin-serve": "^1.1.1", diff --git a/packages/oauth/oauth-client-browser-example/src/app.tsx b/packages/oauth/oauth-client-browser-example/src/app.tsx index 82e01236170..d9c99008b0d 100644 --- a/packages/oauth/oauth-client-browser-example/src/app.tsx +++ b/packages/oauth/oauth-client-browser-example/src/app.tsx @@ -1,6 +1,6 @@ import { useCallback, useState } from 'react' -import { useAuthContext } from './auth/auth-provider' import { OAuthSession } from '@atproto/oauth-client' +import { useAuthContext } from './auth/auth-provider' function App() { const { pdsAgent, signOut, refresh } = useAuthContext() @@ -18,7 +18,7 @@ function App() { const [serviceAuth, setServiceAuth] = useState(undefined) const loadServiceAuth = useCallback(async () => { const serviceAuth = await pdsAgent.com.atproto.server.getServiceAuth({ - aud: pdsAgent.accountDid, + aud: pdsAgent.assertDid, }) console.log('serviceAuth', serviceAuth) setServiceAuth(serviceAuth.data) @@ -28,7 +28,7 @@ function App() { const [profile, setProfile] = useState(undefined) const loadProfile = useCallback(async () => { const profile = await pdsAgent.com.atproto.repo.getRecord({ - repo: pdsAgent.accountDid, + repo: pdsAgent.assertDid, collection: 'app.bsky.actor.profile', rkey: 'self', }) diff --git a/packages/oauth/oauth-client-browser-example/src/auth/auth-form.tsx b/packages/oauth/oauth-client-browser-example/src/auth/auth-form.tsx index acec28717c5..3fa50b1f7a4 100644 --- a/packages/oauth/oauth-client-browser-example/src/auth/auth-form.tsx +++ b/packages/oauth/oauth-client-browser-example/src/auth/auth-form.tsx @@ -1,18 +1,17 @@ import { useEffect, useState } from 'react' - import { AtpSignIn, CredentialSignInForm, } from './credential/credential-sign-in-form' import { OAuthSignIn, OAuthSignInForm } from './oauth/oauth-sign-in-form' -export function AuthForm({ - atpSignIn, - oauthSignIn, -}: { +export type AuthFormProps = { atpSignIn?: AtpSignIn oauthSignIn?: OAuthSignIn -}) { + signUpUrl?: string +} + +export function AuthForm({ atpSignIn, oauthSignIn, signUpUrl }: AuthFormProps) { const defaultMethod = oauthSignIn ? 'oauth' : atpSignIn @@ -58,7 +57,9 @@ export function AuthForm({ - {method === 'oauth' && } + {method === 'oauth' && ( + + )} {method === 'credential' && } {method == null &&
No auth method available
} diff --git a/packages/oauth/oauth-client-browser-example/src/auth/auth-provider.tsx b/packages/oauth/oauth-client-browser-example/src/auth/auth-provider.tsx index 4ddc18ececd..c7b0b951975 100644 --- a/packages/oauth/oauth-client-browser-example/src/auth/auth-provider.tsx +++ b/packages/oauth/oauth-client-browser-example/src/auth/auth-provider.tsx @@ -1,26 +1,31 @@ 'use client' +import { ReactNode, createContext, useContext, useMemo } from 'react' import { Agent } from '@atproto/api' -import { createContext, ReactNode, useContext, useMemo } from 'react' - -import { useCredentialAuth } from './credential/use-credential-auth' import { AuthForm } from './auth-form' -import { useOAuth, UseOAuthOptions } from './oauth/use-oauth' +import { useCredentialAuth } from './credential/use-credential-auth' +import { UseOAuthOptions, useOAuth } from './oauth/use-oauth' -export type AuthContext = { +export type AuthContextValue = { pdsAgent: Agent signOut: () => void refresh: () => void } -const AuthContext = createContext(null) +const AuthContext = createContext(null) + +export type AuthProviderProps = UseOAuthOptions & { + children: ReactNode + signUpUrl?: string +} export const AuthProvider = ({ children, + signUpUrl, + + // UseOAuthOptions ...options -}: { - children: ReactNode -} & UseOAuthOptions) => { +}: AuthProviderProps) => { const { isLoginPopup, isInitializing, @@ -38,7 +43,7 @@ export const AuthProvider = ({ refresh: credentialRefresh, } = useCredentialAuth() - const value = useMemo(() => { + const value = useMemo(() => { if (oauthAgent) { return { pdsAgent: oauthAgent, @@ -77,6 +82,7 @@ export const AuthProvider = ({ return ( ) @@ -85,7 +91,7 @@ export const AuthProvider = ({ return {children} } -export function useAuthContext(): AuthContext { +export function useAuthContext(): AuthContextValue { const context = useContext(AuthContext) if (context) return context diff --git a/packages/oauth/oauth-client-browser-example/src/auth/oauth/oauth-sign-in-form.tsx b/packages/oauth/oauth-client-browser-example/src/auth/oauth/oauth-sign-in-form.tsx index c965209aeb3..1f5c8cae1ac 100644 --- a/packages/oauth/oauth-client-browser-example/src/auth/oauth/oauth-sign-in-form.tsx +++ b/packages/oauth/oauth-client-browser-example/src/auth/oauth/oauth-sign-in-form.tsx @@ -1,59 +1,69 @@ +import { FormEvent, JSX, useState } from 'react' import { AuthorizeOptions } from '@atproto/oauth-client-browser' -import { FormEvent, useCallback, useState } from 'react' export type OAuthSignIn = (input: string, options?: AuthorizeOptions) => unknown +export type OAuthSignInFormProps = Omit< + JSX.IntrinsicElements['form'], + 'onSubmit' +> & { + signIn: OAuthSignIn + signUpUrl?: string +} + /** * @returns Nice tailwind css form asking to enter either a handle or the host * to use to login. */ export function OAuthSignInForm({ signIn, + signUpUrl, + + // form + className, ...props -}: { - signIn: OAuthSignIn -} & Omit, 'onSubmit'>) { +}: OAuthSignInFormProps) { const [value, setValue] = useState('') const [error, setError] = useState(null) const [loading, setLoading] = useState(false) - const onSubmit = useCallback( - async (e: FormEvent) => { - e.preventDefault() - if (loading) return + const onSubmit = async (event: FormEvent) => { + event.preventDefault() - setError(null) - setLoading(true) + if (loading) return + if (!event.currentTarget.reportValidity()) return - try { - if (value.startsWith('did:')) { - if (value.length > 5) await signIn(value) - else setError('DID must be at least 6 characters') - } else if ( - value.startsWith('https://') || - value.startsWith('http://') - ) { - const url = new URL(value) - if (value !== url.origin) throw new Error('PDS URL must be a origin') - await signIn(value) - } else if (value.includes('.') && value.length > 3) { - const handle = value.startsWith('@') ? value.slice(1) : value - if (handle.length > 3) await signIn(handle) - else setError('Handle must be at least 4 characters') - } + setError(null) + setLoading(true) - throw new Error('Please provide a valid handle, DID or PDS URL') - } catch (err) { - setError((err as any)?.message || String(err)) - } finally { - setLoading(false) + try { + if (value.startsWith('did:')) { + if (value.length > 5) await signIn(value) + else setError('DID must be at least 6 characters') + } else if (value.startsWith('https://') || value.startsWith('http://')) { + const url = new URL(value) + if (value !== url.origin) throw new Error('PDS URL must be a origin') + await signIn(value) + } else if (value.includes('.') && value.length > 3) { + const handle = value.startsWith('@') ? value.slice(1) : value + if (handle.length > 3) await signIn(handle) + else setError('Handle must be at least 4 characters') } - }, - [loading, value, signIn], - ) + + throw new Error('Please provide a valid handle, DID or PDS URL') + } catch (err) { + setError((err as any)?.message || String(err)) + } finally { + setLoading(false) + } + } return ( -
+
+ {signUpUrl && ( + + )} + {error ?
{error}
: null}
) diff --git a/packages/oauth/oauth-client-browser-example/src/auth/oauth/use-oauth.ts b/packages/oauth/oauth-client-browser-example/src/auth/oauth/use-oauth.ts index 9bd414f969a..3d77cb8d058 100644 --- a/packages/oauth/oauth-client-browser-example/src/auth/oauth/use-oauth.ts +++ b/packages/oauth/oauth-client-browser-example/src/auth/oauth/use-oauth.ts @@ -151,7 +151,7 @@ export function useOAuth(options: UseOAuthOptions) { const [isInitializing, setIsInitializing] = useState(true) const [isLoginPopup, setIsLoginPopup] = useState(false) - const clientForInitRef = useRef() + const clientForInitRef = useRef(null) useEffect(() => { // In strict mode, we don't want to re-init() the client if it's the same if (clientForInitRef.current === clientForInit) return diff --git a/packages/oauth/oauth-client-browser-example/src/constants.ts b/packages/oauth/oauth-client-browser-example/src/constants.ts index f437722747d..48962659c89 100644 --- a/packages/oauth/oauth-client-browser-example/src/constants.ts +++ b/packages/oauth/oauth-client-browser-example/src/constants.ts @@ -12,3 +12,7 @@ export const PLC_DIRECTORY_URL: string | undefined = export const HANDLE_RESOLVER_URL: string = searchParams.get('handle_resolver') ?? (ENV === 'development' ? 'http://localhost:2584' : 'https://bsky.social') + +export const SIGN_UP_URL: string = + searchParams.get('sign_up_url') ?? + (ENV === 'development' ? 'http://localhost:2583' : 'https://bsky.social') diff --git a/packages/oauth/oauth-client-browser-example/src/main.tsx b/packages/oauth/oauth-client-browser-example/src/main.tsx index fdf51f138f7..c5679b7a898 100644 --- a/packages/oauth/oauth-client-browser-example/src/main.tsx +++ b/packages/oauth/oauth-client-browser-example/src/main.tsx @@ -1,11 +1,15 @@ import './index.css' -import React from 'react' -import ReactDOM from 'react-dom/client' - +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' import App from './app' import { AuthProvider } from './auth/auth-provider' -import { ENV, HANDLE_RESOLVER_URL, PLC_DIRECTORY_URL } from './constants' +import { + ENV, + HANDLE_RESOLVER_URL, + PLC_DIRECTORY_URL, + SIGN_UP_URL, +} from './constants' const clientId = `http://localhost?${new URLSearchParams({ scope: 'atproto transition:generic', @@ -14,20 +18,22 @@ const clientId = `http://localhost?${new URLSearchParams({ search: new URLSearchParams({ env: ENV, handle_resolver: HANDLE_RESOLVER_URL, + sign_up_url: SIGN_UP_URL, ...(PLC_DIRECTORY_URL && { plc_directory_url: PLC_DIRECTORY_URL }), }).toString(), }).href, })}` -ReactDOM.createRoot(document.getElementById('root')!).render( - +createRoot(document.getElementById('root')!).render( + - , + , ) diff --git a/packages/oauth/oauth-client-browser-example/tailwind.config.js b/packages/oauth/oauth-client-browser-example/tailwind.config.js index aea8d354b11..50ce094366b 100644 --- a/packages/oauth/oauth-client-browser-example/tailwind.config.js +++ b/packages/oauth/oauth-client-browser-example/tailwind.config.js @@ -5,4 +5,6 @@ export default { extend: {}, }, plugins: [], + // See rollup.config.js for classes used in the HTML template + safelist: ['bg-white', 'dark:bg-slate-800'], } diff --git a/packages/oauth/oauth-client/src/oauth-response-error.ts b/packages/oauth/oauth-client/src/oauth-response-error.ts index 5c08a0f4d19..de6d17b194a 100644 --- a/packages/oauth/oauth-client/src/oauth-response-error.ts +++ b/packages/oauth/oauth-client/src/oauth-response-error.ts @@ -1,4 +1,5 @@ -import { Json, ifObject, ifString } from '@atproto-labs/fetch' +import { Json } from '@atproto-labs/fetch' +import { ifString } from './util.js' export class OAuthResponseError extends Error { readonly error?: string @@ -8,8 +9,9 @@ export class OAuthResponseError extends Error { public readonly response: Response, public readonly payload: Json, ) { - const error = ifString(ifObject(payload)?.['error']) - const errorDescription = ifString(ifObject(payload)?.['error_description']) + const objPayload = typeof payload === 'object' ? payload : undefined + const error = ifString(objPayload?.['error']) + const errorDescription = ifString(objPayload?.['error_description']) const messageError = error ? `"${error}"` : 'unknown' const messageDesc = errorDescription ? `: ${errorDescription}` : '' diff --git a/packages/oauth/oauth-client/src/util.ts b/packages/oauth/oauth-client/src/util.ts index eef60c18654..051c19a6ec8 100644 --- a/packages/oauth/oauth-client/src/util.ts +++ b/packages/oauth/oauth-client/src/util.ts @@ -4,6 +4,8 @@ export type Simplify = { [K in keyof T]: T[K] } & NonNullable // @ts-expect-error Symbol.dispose ??= Symbol('@@dispose') +export const ifString = (v: V) => (typeof v === 'string' ? v : undefined) + /** * @todo (?) move to common package */ diff --git a/packages/oauth/oauth-provider/.gitignore b/packages/oauth/oauth-provider/.gitignore new file mode 100644 index 00000000000..836c7e6428d --- /dev/null +++ b/packages/oauth/oauth-provider/.gitignore @@ -0,0 +1,2 @@ +src/assets/app/locales/*/*.js +.swc diff --git a/packages/oauth/oauth-provider/.linguirc b/packages/oauth/oauth-provider/.linguirc new file mode 100644 index 00000000000..c0fbfd48964 --- /dev/null +++ b/packages/oauth/oauth-provider/.linguirc @@ -0,0 +1,56 @@ +{ + "format": "po", + "sourceLocale": "en", + "locales": [ + "en", + "an", + "ast", + "ca", + "da", + "de", + "el", + "en-GB", + "es", + "eu", + "fi", + "fr", + "ga", + "gl", + "hi", + "hu", + "ia", + "id", + "it", + "ja", + "km", + "ko", + "ne", + "nl", + "pl", + "pt-BR", + "ro", + "ru", + "sv", + "th", + "tr", + "uk", + "vi", + "zh-CN", + "zh-HK", + "zh-TW" + ], + "fallbackLocales": { + "default": "en" + }, + "catalogs": [ + { + "path": "/src/assets/app/locales/{locale}/messages", + "include": [ + "/src/assets/app" + ], + "exclude": [ + "**/node_modules/**" + ] + } + ] +} diff --git a/packages/oauth/oauth-provider/package.json b/packages/oauth/oauth-provider/package.json index 9f43d55d2a3..217c1795181 100644 --- a/packages/oauth/oauth-provider/package.json +++ b/packages/oauth/oauth-provider/package.json @@ -41,9 +41,11 @@ "@atproto/jwk-jose": "workspace:*", "@atproto/oauth-types": "workspace:*", "@hapi/accept": "^6.0.3", + "@hapi/address": "^5.1.1", "@hapi/bourne": "^3.0.0", "@hapi/content": "^6.0.0", "cookie": "^0.6.0", + "disposable-email-domains-js": "^1.5.0", "forwarded": "^0.2.0", "http-errors": "^2.0.0", "ioredis": "^5.3.2", @@ -52,29 +54,37 @@ "zod": "^3.23.8" }, "devDependencies": { - "@atproto-labs/rollup-plugin-bundle-manifest": "workspace:*", - "@rollup/plugin-commonjs": "^25.0.7", - "@rollup/plugin-node-resolve": "^15.2.3", - "@rollup/plugin-replace": "^5.0.5", - "@rollup/plugin-terser": "^0.4.4", - "@rollup/plugin-typescript": "^11.1.6", + "@atproto-labs/rollup-plugin-bundle-manifest": "workspace:^", + "@hcaptcha/react-hcaptcha": "^1.11.2", + "@lingui/cli": "^5.2.0", + "@lingui/core": "^5.2.0", + "@lingui/react": "^5.2.0", + "@lingui/swc-plugin": "^5.4.0", + "@rollup/plugin-commonjs": "^28.0.2", + "@rollup/plugin-node-resolve": "^16.0.0", + "@rollup/plugin-swc": "^0.4.0", + "@swc/core": "^1.10.18", + "@swc/helpers": "^0.5.15", "@types/cookie": "^0.6.0", "@types/forwarded": "0.1.3", "@types/psl": "1.1.3", - "@types/react": "^18.2.50", - "@types/react-dom": "^18.2.18", + "@types/react": "^19.0.10", + "@types/react-dom": "^19.0.4", "@types/send": "^0.17.4", "@web/rollup-plugin-import-meta-assets": "^2.2.1", "autoprefixer": "^10.4.17", "postcss": "^8.4.33", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "react-error-boundary": "^5.0.0", "rollup": "^4.13.0", "rollup-plugin-postcss": "^4.0.2", "tailwindcss": "^3.4.1", "typescript": "^5.6.3" }, "scripts": { + "extract": "lingui extract", + "prebuild:frontend": "lingui compile", "build:frontend": "rollup --config rollup.config.js", "build:backend": "tsc --build --force tsconfig.backend.json", "build": "pnpm --parallel --stream '/^build:.+$/'", diff --git a/packages/oauth/oauth-provider/rollup.config.js b/packages/oauth/oauth-provider/rollup.config.js index 7ff599c3a65..158a4bfec17 100644 --- a/packages/oauth/oauth-provider/rollup.config.js +++ b/packages/oauth/oauth-provider/rollup.config.js @@ -2,53 +2,99 @@ const { default: commonjs } = require('@rollup/plugin-commonjs') const { default: nodeResolve } = require('@rollup/plugin-node-resolve') -const { default: replace } = require('@rollup/plugin-replace') -const { default: terser } = require('@rollup/plugin-terser') -const { default: typescript } = require('@rollup/plugin-typescript') +const { default: swc } = require('@rollup/plugin-swc') const { defineConfig } = require('rollup') const { default: manifest, } = require('@atproto-labs/rollup-plugin-bundle-manifest') const postcss = ((m) => m.default || m)(require('rollup-plugin-postcss')) -module.exports = defineConfig((commandLineArguments) => { - const NODE_ENV = - process.env['NODE_ENV'] ?? - (commandLineArguments.watch ? 'development' : 'production') +module.exports = defineConfig( + /** + * @returns {import('rollup').RollupOptions} + */ + (commandLineArguments) => { + const NODE_ENV = + process.env['NODE_ENV'] ?? + (commandLineArguments.watch ? 'development' : 'production') - const minify = NODE_ENV !== 'development' + const devMode = NODE_ENV === 'development' - return { - input: 'src/assets/app/main.tsx', - output: { - manualChunks: undefined, - sourcemap: true, - file: 'dist/assets/app/main.js', - format: 'iife', - }, - plugins: [ - nodeResolve({ preferBuiltins: false, browser: true }), - commonjs(), - postcss({ config: true, extract: true, minimize: minify }), - typescript({ - tsconfig: './tsconfig.frontend.json', - outputToFilesystem: true, - }), - replace({ - preventAssignment: true, - values: { 'process.env.NODE_ENV': JSON.stringify(NODE_ENV) }, - }), - // Change `data` to `true` to include assets data in the manifest, - // allowing for easier bundling of the backend code (eg. using esbuild) as - // bundlers know how to bundle JSON files but not how to bundle assets - // referenced at runtime. - manifest({ data: false }), - minify && terser({}), - ], - onwarn(warning, warn) { - // 'use client' directives are fine - if (warning.code === 'MODULE_LEVEL_DIRECTIVE') return - warn(warning) - }, - } -}) + return { + input: 'src/assets/app/main.tsx', + output: { + manualChunks: undefined, + sourcemap: true, + file: 'dist/assets/app/main.js', + format: 'iife', + }, + plugins: [ + { + name: 'resolve-swc-helpers', + resolveId(src) { + // For some reason, "nodeResolve" doesn't resolve these: + if (src.startsWith('@swc/helpers/')) return require.resolve(src) + }, + }, + nodeResolve({ + preferBuiltins: false, + browser: true, + exportConditions: ['browser', 'module', 'import', 'default'], + }), + commonjs(), + postcss({ config: true, extract: true, minimize: !devMode }), + swc({ + swc: { + swcrc: false, + configFile: false, + sourceMaps: true, + minify: !devMode, + jsc: { + experimental: { + // @NOTE Because of the experimental nature of SWC plugins, A + // very particular version of @swc/core needs to be used. The + // link below allows to determine with version of @swc/core is + // compatible based on the version of @lingui/swc-plugin used + // (click on the swc_core version in the right column to see + // which version of the @swc/core is compatible) + // + // https://github.com/lingui/swc-plugin?tab=readme-ov-file#compatibility + plugins: [['@lingui/swc-plugin', {}]], + }, + minify: { + compress: { + module: true, + unused: true, + }, + mangle: true, + }, + externalHelpers: true, + target: 'es2020', + parser: { syntax: 'typescript', tsx: true }, + transform: { + useDefineForClassFields: true, + react: { runtime: 'automatic' }, + optimizer: { + simplify: true, + globals: { + vars: { 'process.env.NODE_ENV': JSON.stringify(NODE_ENV) }, + }, + }, + }, + }, + }, + }), + // Change `data` to `true` to include assets data in the manifest, + // allowing for easier bundling of the backend code (eg. using esbuild) as + // bundlers know how to bundle JSON files but not how to bundle assets + // referenced at runtime. + manifest({ data: false }), + ], + onwarn(warning, warn) { + // 'use client' directives are fine + if (warning.code === 'MODULE_LEVEL_DIRECTIVE') return + warn(warning) + }, + } + }, +) diff --git a/packages/oauth/oauth-provider/src/account/account-manager.ts b/packages/oauth/oauth-provider/src/account/account-manager.ts index 64a8b8c1b0e..e4f1e017fe5 100644 --- a/packages/oauth/oauth-provider/src/account/account-manager.ts +++ b/packages/oauth/oauth-provider/src/account/account-manager.ts @@ -1,31 +1,161 @@ -import { isOAuthClientIdLoopback } from '@atproto/oauth-types' +import { + OAuthIssuerIdentifier, + isOAuthClientIdLoopback, +} from '@atproto/oauth-types' import { Client } from '../client/client.js' import { DeviceId } from '../device/device-id.js' +import { InvalidRequestError } from '../errors/invalid-request-error.js' +import { HCaptchaClient, HcaptchaVerifyResult } from '../lib/hcaptcha.js' +import { callAsync } from '../lib/util/function.js' import { constantTime } from '../lib/util/time.js' -import { InvalidRequestError } from '../oauth-errors.js' +import { OAuthHooks, RequestMetadata } from '../oauth-hooks.js' +import { Customization } from '../oauth-provider.js' import { Sub } from '../oidc/sub.js' import { ClientAuth } from '../token/token-store.js' import { Account, AccountInfo, AccountStore, - SignInCredentials, + ResetPasswordConfirmData, + ResetPasswordRequestData, } from './account-store.js' +import { SignInData } from './sign-in-data.js' +import { SignUpData } from './sign-up-data.js' const TIMING_ATTACK_MITIGATION_DELAY = 400 export class AccountManager { - constructor(protected readonly store: AccountStore) {} + protected readonly inviteCodeRequired: boolean + protected readonly hcaptchaClient?: HCaptchaClient + + constructor( + issuer: OAuthIssuerIdentifier, + protected readonly store: AccountStore, + protected readonly hooks: OAuthHooks, + customization: Customization, + ) { + this.inviteCodeRequired = customization.inviteCodeRequired !== false + this.hcaptchaClient = customization.hcaptcha + ? new HCaptchaClient(new URL(issuer).hostname, customization.hcaptcha) + : undefined + } + + protected async verifySignupData( + data: SignUpData, + deviceId: DeviceId, + deviceMetadata: RequestMetadata, + ): Promise { + let hcaptchaResult: undefined | HcaptchaVerifyResult + + if (this.inviteCodeRequired && !data.inviteCode) { + throw new InvalidRequestError('Invite code is required') + } + + if (this.hcaptchaClient) { + if (!data.hcaptchaToken) { + throw new InvalidRequestError('hCaptcha token is required') + } + + const { allowed, result } = await this.hcaptchaClient.verify( + 'signup', + data.hcaptchaToken, + deviceMetadata.ipAddress, + data.handle, + deviceMetadata.userAgent, + ) + + await callAsync(this.hooks.onSignupHcaptchaResult, { + data, + allowed, + result, + deviceId, + deviceMetadata, + }) + + if (!allowed) { + throw new InvalidRequestError('hCaptcha verification failed') + } + + hcaptchaResult = result + } + + await callAsync(this.hooks.onSignupAttempt, { + data, + deviceId, + deviceMetadata, + hcaptchaResult, + }) + } + + public async signUp( + data: SignUpData, + deviceId: DeviceId, + deviceMetadata: RequestMetadata, + ): Promise { + await this.verifySignupData(data, deviceId, deviceMetadata) + + return constantTime(TIMING_ATTACK_MITIGATION_DELAY, async () => { + let account: Account + try { + account = await this.store.createAccount(data) + } catch (err) { + throw InvalidRequestError.from(err, 'Account creation failed') + } + + try { + const info = await this.store.addDeviceAccount( + deviceId, + account.sub, + false, + ) + + await callAsync(this.hooks.onSignedUp, { + data, + info, + account, + deviceId, + deviceMetadata, + }) + + return { account, info } + } catch (err) { + throw InvalidRequestError.from( + err, + 'Something went wrong, try singing-in', + ) + } + }) + } public async signIn( - credentials: SignInCredentials, + data: SignInData, deviceId: DeviceId, + deviceMetadata: RequestMetadata, ): Promise { return constantTime(TIMING_ATTACK_MITIGATION_DELAY, async () => { - const result = await this.store.authenticateAccount(credentials, deviceId) - if (result) return result + try { + const account = await this.store.authenticateAccount(data) + const info = await this.store.addDeviceAccount( + deviceId, + account.sub, + data.remember, + ) + + await callAsync(this.hooks.onSignedIn, { + data, + info, + account, + deviceId, + deviceMetadata, + }) - throw new InvalidRequestError('Invalid credentials') + return { account, info } + } catch (err) { + throw InvalidRequestError.from( + err, + 'Unable to sign-in due to an unexpected server error', + ) + } }) } @@ -52,4 +182,22 @@ export class AccountManager { const results = await this.store.listDeviceAccounts(deviceId) return results.filter((result) => result.info.remembered) } + + public async resetPasswordRequest(data: ResetPasswordRequestData) { + return constantTime(TIMING_ATTACK_MITIGATION_DELAY, async () => { + await this.store.resetPasswordRequest(data) + }) + } + + public async resetPasswordConfirm(data: ResetPasswordConfirmData) { + return constantTime(TIMING_ATTACK_MITIGATION_DELAY, async () => { + await this.store.resetPasswordConfirm(data) + }) + } + + public async verifyHandleAvailability(handle: string): Promise { + return constantTime(TIMING_ATTACK_MITIGATION_DELAY, async () => { + return this.store.verifyHandleAvailability(handle) + }) + } } diff --git a/packages/oauth/oauth-provider/src/account/account-store.ts b/packages/oauth/oauth-provider/src/account/account-store.ts index ad49f8d98eb..161d8d07bc1 100644 --- a/packages/oauth/oauth-provider/src/account/account-store.ts +++ b/packages/oauth/oauth-provider/src/account/account-store.ts @@ -1,25 +1,83 @@ +import { isEmailValid } from '@hapi/address' +import { isDisposableEmail } from 'disposable-email-domains-js' import { z } from 'zod' import { ClientId } from '../client/client-id.js' import { DeviceId } from '../device/device-id.js' import { Awaitable } from '../lib/util/type.js' +import { + HandleUnavailableError, + InvalidRequestError, + SecondAuthenticationFactorRequiredError, +} from '../oauth-errors.js' import { Sub } from '../oidc/sub.js' import { Account } from './account.js' -export const signInCredentialsSchema = z.object({ - username: z.string(), - password: z.string(), +// @NOTE Change the length here to force stronger passwords (through a reset) +export const oldPasswordSchema = z.string().min(1) +export const newPasswordSchema = z.string().min(8) +export const tokenSchema = z.string().regex(/^[A-Z2-7]{5}-[A-Z2-7]{5}$/) +export const handleSchema = z + .string() + .min(3) + .max(18) + .regex(/^[a-z0-9][a-z0-9-]+[a-z0-9]$/) +export const emailSchema = z + .string() + .email() + // @NOTE using @hapi/address here, in addition to the email() check to ensure + // compatibility with the current email validation in the PDS's account + // manager + .refine(isEmailValid, { + message: 'Invalid email address', + }) + .refine((email) => !isDisposableEmail(email), { + message: 'Disposable email addresses are not allowed', + }) - /** - * If false, the account must not be returned from - * {@link AccountStore.listDeviceAccounts}. Note that this only makes sense when - * used with a device ID. - */ - remember: z.boolean().optional().default(false), +export const authenticateAccountDataSchema = z + .object({ + username: z.string(), + password: oldPasswordSchema, + emailOtp: z.string().optional(), + }) + .strict() + +export type AuthenticateAccountData = z.TypeOf< + typeof authenticateAccountDataSchema +> + +export const createAccountDataSchema = z + .object({ + handle: handleSchema, + email: emailSchema, + password: z.intersection(oldPasswordSchema, newPasswordSchema), + birthdate: z.string().date(), + inviteCode: tokenSchema.optional(), + }) + .strict() + +export type CreateAccountData = z.TypeOf + +export const resetPasswordRequestDataSchema = z + .object({ + email: emailSchema, + }) + .strict() + +export type ResetPasswordRequestData = z.TypeOf< + typeof resetPasswordRequestDataSchema +> - emailOtp: z.string().optional(), -}) +export const resetPasswordConfirmDataSchema = z + .object({ + token: tokenSchema, + password: z.intersection(oldPasswordSchema, newPasswordSchema), + }) + .strict() -export type SignInCredentials = z.TypeOf +export type ResetPasswordConfirmData = z.TypeOf< + typeof resetPasswordConfirmDataSchema +> export type DeviceAccountInfo = { remembered: boolean @@ -28,7 +86,14 @@ export type DeviceAccountInfo = { } // Export all types needed to implement the AccountStore interface -export type { Account, DeviceId, Sub } +export { + type Account, + type DeviceId, + HandleUnavailableError, + InvalidRequestError, + SecondAuthenticationFactorRequiredError, + type Sub, +} export type AccountInfo = { account: Account @@ -36,10 +101,17 @@ export type AccountInfo = { } export interface AccountStore { - authenticateAccount( - credentials: SignInCredentials, - deviceId: DeviceId, - ): Awaitable + /** + * @throws {HandleUnavailableError} - To indicate that the handle is already taken + * @throws {InvalidRequestError} - To indicate that some data is invalid + */ + createAccount(data: CreateAccountData): Awaitable + + /** + * @throws {InvalidRequestError} - When the credentials are not valid + * @throws {SecondAuthenticationFactorRequiredError} - To indicate that an {@link SecondAuthenticationFactorRequiredError.type} is required in the credentials + */ + authenticateAccount(data: AuthenticateAccountData): Awaitable addAuthorizedClient( deviceId: DeviceId, @@ -47,6 +119,19 @@ export interface AccountStore { clientId: ClientId, ): Awaitable + /** + * @param remember If false, the account must not be returned from + * {@link AccountStore.listDeviceAccounts}. + */ + addDeviceAccount( + deviceId: DeviceId, + sub: Sub, + remember: boolean, + ): Awaitable + + /** + * @returns The account info, whether the account, even if remember was false. + */ getDeviceAccount(deviceId: DeviceId, sub: Sub): Awaitable removeDeviceAccount(deviceId: DeviceId, sub: Sub): Awaitable @@ -55,6 +140,14 @@ export interface AccountStore { * be returned. The others will be ignored. */ listDeviceAccounts(deviceId: DeviceId): Awaitable + + resetPasswordRequest(data: ResetPasswordRequestData): Awaitable + resetPasswordConfirm(data: ResetPasswordConfirmData): Awaitable + + /** + * @throws {HandleUnavailableError} - To indicate that the handle is already taken + */ + verifyHandleAvailability(handle: string): Awaitable } export function isAccountStore( @@ -62,10 +155,14 @@ export function isAccountStore( ): implementation is Record & AccountStore { return ( typeof implementation.authenticateAccount === 'function' && + typeof implementation.addDeviceAccount === 'function' && typeof implementation.getDeviceAccount === 'function' && typeof implementation.addAuthorizedClient === 'function' && typeof implementation.listDeviceAccounts === 'function' && - typeof implementation.removeDeviceAccount === 'function' + typeof implementation.removeDeviceAccount === 'function' && + typeof implementation.resetPasswordRequest === 'function' && + typeof implementation.resetPasswordConfirm === 'function' && + typeof implementation.verifyHandleAvailability === 'function' ) } diff --git a/packages/oauth/oauth-provider/src/account/sign-in-data.ts b/packages/oauth/oauth-provider/src/account/sign-in-data.ts new file mode 100644 index 00000000000..47a742a3a7e --- /dev/null +++ b/packages/oauth/oauth-provider/src/account/sign-in-data.ts @@ -0,0 +1,15 @@ +import { z } from 'zod' +import { authenticateAccountDataSchema } from './account-store.js' + +export const signInDataSchema = authenticateAccountDataSchema + .extend({ + /** + * If false, the account must not be returned from + * {@link AccountStore.listDeviceAccounts}. Note that this only makes sense when + * used with a device ID. + */ + remember: z.boolean().optional().default(false), + }) + .strict() + +export type SignInData = z.TypeOf diff --git a/packages/oauth/oauth-provider/src/account/sign-up-data.ts b/packages/oauth/oauth-provider/src/account/sign-up-data.ts new file mode 100644 index 00000000000..cf9aac8abd1 --- /dev/null +++ b/packages/oauth/oauth-provider/src/account/sign-up-data.ts @@ -0,0 +1,11 @@ +import { z } from 'zod' +import { hcaptchaTokenSchema } from '../lib/hcaptcha.js' +import { createAccountDataSchema } from './account-store.js' + +export const signUpDataSchema = createAccountDataSchema + .extend({ + hcaptchaToken: hcaptchaTokenSchema.optional(), + }) + .strict() + +export type SignUpData = z.TypeOf diff --git a/packages/oauth/oauth-provider/src/assets/app/app.tsx b/packages/oauth/oauth-provider/src/assets/app/app.tsx index e925ffae5dd..00052b64907 100644 --- a/packages/oauth/oauth-provider/src/assets/app/app.tsx +++ b/packages/oauth/oauth-provider/src/assets/app/app.tsx @@ -1,10 +1,14 @@ +import { i18n } from '@lingui/core' +import { I18nProvider } from '@lingui/react' +import { ErrorBoundary } from 'react-error-boundary' import type { AuthorizeData, CustomizationData, ErrorData, -} from './backend-data' -import { AuthorizeView } from './views/authorize-view' -import { ErrorView } from './views/error-view' +} from './backend-types.ts' +import * as allMessages from './locales/index.ts' +import { AuthorizeView } from './views/authorize/authorize-view.tsx' +import { ErrorView } from './views/error/error-view.tsx' export type AppProps = { authorizeData?: AuthorizeData @@ -12,17 +16,26 @@ export type AppProps = { errorData?: ErrorData } +i18n.load(allMessages) +i18n.activate('en') + export function App({ authorizeData, customizationData, errorData }: AppProps) { - if (authorizeData && !errorData) { - return ( - - ) - } else { - return ( - - ) - } + return ( + + ( + + )} + > + {errorData || !authorizeData ? ( + + ) : ( + + )} + + + ) } diff --git a/packages/oauth/oauth-provider/src/assets/app/backend-data.ts b/packages/oauth/oauth-provider/src/assets/app/backend-data.ts index ae9f4874812..b4834190ed1 100644 --- a/packages/oauth/oauth-provider/src/assets/app/backend-data.ts +++ b/packages/oauth/oauth-provider/src/assets/app/backend-data.ts @@ -1,72 +1,19 @@ -import { OAuthClientMetadata } from '@atproto/oauth-types' +import { AuthorizeData, CustomizationData, ErrorData } from './backend-types.ts' -// TODO: Find a way to share these types with the backend code - -export type Account = { - sub: string - aud: string - - email?: string - name?: string - preferred_username?: string - picture?: string -} - -export type Session = { - account: Account - info?: never // Prevent relying on this in the frontend - - selected: boolean - loginRequired: boolean - consentRequired: boolean -} - -export type LinkDefinition = { - title: string - href: string - rel?: string -} - -export type CustomizationData = { - name?: string - logo?: string - links?: LinkDefinition[] -} - -export type ErrorData = { - error: string - error_description: string -} - -export type ScopeDetail = { - scope: string - description?: string -} - -export type AuthorizeData = { - clientId: string - clientMetadata: OAuthClientMetadata - clientTrusted: boolean - requestUri: string - csrfCookie: string - loginHint?: string - scopeDetails?: ScopeDetail[] - newSessionsRequireConsent: boolean - sessions: Session[] -} - -// see "declareBackendData()" in the backend -const readBackendData = (key: string): T | undefined => { +function readBackendData(key: string): T | undefined { const value = window[key] as T | undefined delete window[key] // Prevent accidental usage / potential leaks to dependencies return value } // These values are injected by the backend when it builds the -// page HTML. +// page HTML. See "declareBackendData()" in the backend. +/** @deprecated Do not import directly. Only import this from main.tsx */ export const customizationData = readBackendData( '__customizationData', ) +/** @deprecated Do not import directly. Only import this from main.tsx */ export const errorData = readBackendData('__errorData') +/** @deprecated Do not import directly. Only import this from main.tsx */ export const authorizeData = readBackendData('__authorizeData') diff --git a/packages/oauth/oauth-provider/src/assets/app/backend-types.ts b/packages/oauth/oauth-provider/src/assets/app/backend-types.ts new file mode 100644 index 00000000000..60635041ec7 --- /dev/null +++ b/packages/oauth/oauth-provider/src/assets/app/backend-types.ts @@ -0,0 +1,61 @@ +import type { OAuthClientMetadata } from '@atproto/oauth-types' + +// TODO: Find a way to share these types with the backend code + +export type Account = { + sub: string + aud: string + + email?: string + name?: string + preferred_username?: string + picture?: string +} + +export type Session = { + account: Account + info?: never // Prevent relying on this in the frontend + + selected: boolean + loginRequired: boolean + consentRequired: boolean +} + +export type LinkDefinition = { + title: string + href: string + rel?: string +} + +export type CustomizationData = { + // Functional customization + hcaptchaSiteKey?: string + inviteCodeRequired?: boolean + availableUserDomains?: string[] + + // Aesthetic customization + name?: string + logo?: string + links?: LinkDefinition[] +} + +export type ErrorData = { + error: string + error_description: string +} + +export type ScopeDetail = { + scope: string + description?: string +} + +export type AuthorizeData = { + clientId: string + clientMetadata: OAuthClientMetadata + clientTrusted: boolean + requestUri: string + loginHint?: string + scopeDetails?: ScopeDetail[] + newSessionsRequireConsent: boolean + sessions: Session[] +} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/accept-form.tsx b/packages/oauth/oauth-provider/src/assets/app/components/accept-form.tsx deleted file mode 100644 index 27c2a1aecbf..00000000000 --- a/packages/oauth/oauth-provider/src/assets/app/components/accept-form.tsx +++ /dev/null @@ -1,137 +0,0 @@ -import { OAuthClientMetadata } from '@atproto/oauth-types' -import { FormEvent } from 'react' - -import { Account, ScopeDetail } from '../backend-data' -import { Override } from '../lib/util' -import { AccountIdentifier } from './account-identifier' -import { Button } from './button' -import { ClientName } from './client-name' -import { FormCard, FormCardProps } from './form-card' - -export type AcceptFormProps = Override< - FormCardProps, - { - clientId: string - clientMetadata: OAuthClientMetadata - clientTrusted: boolean - - account: Account - scopeDetails?: ScopeDetail[] - - onAccept: () => void - acceptLabel?: string - - onReject: () => void - rejectLabel?: string - - onBack?: () => void - backLabel?: string - } -> - -export function AcceptForm({ - clientId, - clientMetadata, - clientTrusted, - - account, - scopeDetails, - - onAccept, - acceptLabel = 'Accept', - onReject, - rejectLabel = 'Deny access', - onBack, - backLabel = 'Back', - - ...props -}: AcceptFormProps) { - const doSubmit = (e: FormEvent) => { - e.preventDefault() - onAccept() - } - - return ( - {backLabel}} - actions={ - <> - - - - - } - {...props} - > - {clientTrusted && clientMetadata.logo_uri && ( -
- {clientMetadata.client_name} -
- )} -

- {' '} - is asking for permission to access your account ( - - ). -

- -

- By clicking {acceptLabel}, you allow this application to perform - the following actions in accordance to their{' '} - - terms of service - - {' and '} - - privacy policy - - : -

- - {scopeDetails?.length ? ( -
    - {scopeDetails.map( - ({ scope, description = getScopeDescription(scope) }) => ( -
  • {description}
  • - ), - )} -
- ) : null} -
- ) -} - -function getScopeDescription(scope: string): string { - switch (scope) { - case 'atproto': - return 'Uniquely identify you' - case 'transition:generic': - return 'Access your account data (except chat messages)' - case 'transition:chat.bsky': - return 'Access your chat messages' - default: - return scope - } -} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/account-identifier.tsx b/packages/oauth/oauth-provider/src/assets/app/components/account-identifier.tsx deleted file mode 100644 index 96b860e3261..00000000000 --- a/packages/oauth/oauth-provider/src/assets/app/components/account-identifier.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { HTMLAttributes } from 'react' - -import { Account } from '../backend-data' - -export type AccountIdentifierProps = { - account: Account -} - -export function AccountIdentifier({ - account, - ...attrs -}: AccountIdentifierProps & HTMLAttributes) { - return ( - - {account.preferred_username || account.email || account.sub} - - ) -} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/account-picker.tsx b/packages/oauth/oauth-provider/src/assets/app/components/account-picker.tsx deleted file mode 100644 index 93b195941ad..00000000000 --- a/packages/oauth/oauth-provider/src/assets/app/components/account-picker.tsx +++ /dev/null @@ -1,127 +0,0 @@ -import type { ReactNode } from 'react' -import { Account } from '../backend-data' -import { Override } from '../lib/util' -import { Button } from './button' -import { FormCard, FormCardProps } from './form-card' -import { AtSymbolIcon } from './icons/at-symbol-icon' -import { CaretRightIcon } from './icons/caret-right-icon' -import { InputContainer } from './input-container' -import { Fieldset } from './fieldset' - -export type AccountPickerProps = Override< - FormCardProps, - { - accounts: readonly Account[] - - onAccount: (account: Account) => void - accountAria?: (account: Account) => string - - onOther?: () => void - otherLabel?: ReactNode - otherAria?: string - - onBack?: () => void - backLabel?: ReactNode - backAria?: string - } -> - -export function AccountPicker({ - accounts, - - onAccount, - accountAria = (a) => `Sign in as ${a.name}`, - - onOther = undefined, - otherLabel = 'Another account', - otherAria = 'Login to account that is not listed', - - onBack, - backAria, - backLabel = backAria, - - ...props -}: AccountPickerProps) { - return ( - - {backLabel} - - ) - } - > -
- {accounts.map((account) => { - const [name, identifier] = [ - account.name, - account.preferred_username, - account.email, - account.sub, - ].filter(Boolean) as [string, string?] - - return ( - onAccount(account)} - role="button" - aria-label={accountAria(account)} - icon={ - account.picture ? ( - {name} - ) : ( - - - - - - ) - } - append={} - > - - {name} - {identifier && ( - - {identifier} - - )} - - - ) - })} - - {onOther && ( - } - icon={} - > - - {otherLabel} - - - )} -
-
- ) -} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/button.tsx b/packages/oauth/oauth-provider/src/assets/app/components/button.tsx deleted file mode 100644 index 5900c7241c0..00000000000 --- a/packages/oauth/oauth-provider/src/assets/app/components/button.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { ButtonHTMLAttributes } from 'react' -import { clsx } from '../lib/clsx' - -export function Button({ - children, - className, - type = 'button', - role = 'Button', - color = 'grey', - disabled = false, - loading = undefined, - ...props -}: { - color?: 'brand' | 'grey' - loading?: boolean -} & ButtonHTMLAttributes) { - return ( - - ) -} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/client-name.tsx b/packages/oauth/oauth-provider/src/assets/app/components/client-name.tsx deleted file mode 100644 index 98244d4d289..00000000000 --- a/packages/oauth/oauth-provider/src/assets/app/components/client-name.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { - isOAuthClientIdDiscoverable, - isOAuthClientIdLoopback, - OAuthClientMetadata, -} from '@atproto/oauth-types' -import { HTMLAttributes } from 'react' - -import { UrlViewer } from './url-viewer' - -export type ClientNameProps = { - clientId: string - clientMetadata: OAuthClientMetadata - clientTrusted: boolean - loopbackClientName?: string -} & HTMLAttributes - -export function ClientName({ - clientId, - clientMetadata, - clientTrusted, - loopbackClientName = 'An application on your device', - ...attrs -}: ClientNameProps) { - if (clientTrusted && clientMetadata.client_name) { - return {clientMetadata.client_name} - } - - if (isOAuthClientIdLoopback(clientId)) { - return {loopbackClientName} - } - - if (isOAuthClientIdDiscoverable(clientId)) { - return - } - - return {clientId} -} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/fieldset.tsx b/packages/oauth/oauth-provider/src/assets/app/components/fieldset.tsx deleted file mode 100644 index 4185246c977..00000000000 --- a/packages/oauth/oauth-provider/src/assets/app/components/fieldset.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { FieldsetHTMLAttributes, forwardRef, ReactNode } from 'react' -import { Override } from '../lib/util' - -export type FieldsetCardProps = Override< - FieldsetHTMLAttributes, - { - title?: ReactNode - } -> - -export const Fieldset = forwardRef( - ({ title, children, ...props }, ref) => ( -
- {title && ( -

- {title} -

- )} - -
{children}
-
- ), -) diff --git a/packages/oauth/oauth-provider/src/assets/app/components/form-card.tsx b/packages/oauth/oauth-provider/src/assets/app/components/form-card.tsx deleted file mode 100644 index 029e9867802..00000000000 --- a/packages/oauth/oauth-provider/src/assets/app/components/form-card.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { FormHTMLAttributes, forwardRef, ReactNode } from 'react' -import { InfoCard } from './info-card' -import { clsx } from '../lib/clsx' -import { Override } from '../lib/util' - -export type FormCardProps = Override< - FormHTMLAttributes, - { - append?: ReactNode - error?: ReactNode - cancel?: ReactNode - actions?: ReactNode - } -> - -export const FormCard = forwardRef( - ({ actions, cancel, append, className, children, error, ...props }, ref) => { - return ( -
-
{children}
- - {append &&
{append}
} - - {error && ( - - {error} - - )} - - {(actions || cancel) && ( -
- {actions} -
- {cancel} -
- )} - - ) - }, -) diff --git a/packages/oauth/oauth-provider/src/assets/app/components/forms/button-toggle-visibility.tsx b/packages/oauth/oauth-provider/src/assets/app/components/forms/button-toggle-visibility.tsx new file mode 100644 index 00000000000..c2a887bcf5e --- /dev/null +++ b/packages/oauth/oauth-provider/src/assets/app/components/forms/button-toggle-visibility.tsx @@ -0,0 +1,41 @@ +import { Override } from '../../lib/util.ts' +import { EyeIcon, EyeSlashIcon } from '../utils/icons.tsx' +import { Button, ButtonProps } from './button.tsx' + +export type ButtonToggleVisibilityProps = Override< + Omit, + { + visible: boolean + toggleVisible: () => void + } +> + +/** + * Generic button to toggle visibility of an item (e.g. password). + */ +export function ButtonToggleVisibility({ + visible, + toggleVisible, + + // button + onClick, + ...props +}: ButtonToggleVisibilityProps) { + return ( + + ) +} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/forms/button.tsx b/packages/oauth/oauth-provider/src/assets/app/components/forms/button.tsx new file mode 100644 index 00000000000..5e5f5626db5 --- /dev/null +++ b/packages/oauth/oauth-provider/src/assets/app/components/forms/button.tsx @@ -0,0 +1,60 @@ +import { JSX } from 'react' +import { clsx } from '../../lib/clsx.ts' +import { Override } from '../../lib/util.ts' + +export type ButtonProps = Override< + JSX.IntrinsicElements['button'], + { + color?: 'brand' | 'grey' + loading?: boolean + transparent?: boolean + square?: boolean + } +> + +export function Button({ + color = 'grey', + transparent = false, + loading = undefined, + square = false, + + // button + children, + className, + type = 'button', + role = 'Button', + disabled = false, + ...props +}: ButtonProps) { + return ( + + ) +} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/forms/fieldset.tsx b/packages/oauth/oauth-provider/src/assets/app/components/forms/fieldset.tsx new file mode 100644 index 00000000000..d8b83fea8a2 --- /dev/null +++ b/packages/oauth/oauth-provider/src/assets/app/components/forms/fieldset.tsx @@ -0,0 +1,55 @@ +import { JSX, ReactNode, createContext, useMemo } from 'react' +import { useRandomString } from '../../hooks/use-random-string.ts' +import { Override } from '../../lib/util.ts' + +export type FieldsetContextValue = { + disabled: boolean + labelId?: string +} + +export const FieldsetContext = createContext({ + disabled: false, +}) +FieldsetContext.displayName = 'FieldsetContext' + +export type FieldsetCardProps = Override< + Omit, + { + label?: ReactNode + } +> + +export function Fieldset({ + label, + children, + disabled, + ...props +}: FieldsetCardProps) { + const labelId = useRandomString({ prefix: 'fieldset-' }) + + const contextValue = useMemo( + () => ({ + disabled: disabled ?? false, + labelId: label ? labelId : undefined, + }), + [disabled, label, labelId], + ) + + return ( +
+ {label && ( + + {label} + + )} + +
+ {children} +
+
+ ) +} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/forms/form-card-async.tsx b/packages/oauth/oauth-provider/src/assets/app/components/forms/form-card-async.tsx new file mode 100644 index 00000000000..54744f8260c --- /dev/null +++ b/packages/oauth/oauth-provider/src/assets/app/components/forms/form-card-async.tsx @@ -0,0 +1,100 @@ +import { Trans } from '@lingui/react/macro' +import { ReactNode } from 'react' +import { + UseAsyncActionOptions, + useAsyncAction, +} from '../../hooks/use-async-action.ts' +import { Override } from '../../lib/util.ts' +import { ErrorCard } from '../utils/error-card.tsx' +import { Button } from './button.tsx' +import { FormCard, FormCardProps } from './form-card.tsx' + +export type { AsyncActionController } from '../../hooks/use-async-action.ts' + +export type ErrorRender = (data: { error: Error }) => ReactNode +export const errorRenderDefault: ErrorRender = ({ error }) => ( + +) + +export type FormCardAsyncProps = Override< + Override< + Omit, + Pick + >, + { + invalid?: boolean + disabled?: boolean + + onSubmit: (signal: AbortSignal) => void | PromiseLike + submitLabel?: ReactNode + + onCancel?: () => void + cancelLabel?: ReactNode + + errorRender?: ErrorRender + } +> + +export function FormCardAsync({ + invalid, + disabled, + + onSubmit, + submitLabel, + + onCancel = undefined, + cancelLabel, + + errorRender = errorRenderDefault, + + // UseAsyncActionOptions + ref, + onLoading, + onError, + + // FormCardProps + children, + ...props +}: FormCardAsyncProps) { + const { run, loading, error } = useAsyncAction(onSubmit, { + ref, + onError, + onLoading, + }) + + // @TODO translate button labels + + return ( + { + event.preventDefault() + + if (!event.currentTarget.reportValidity()) return + + if (!disabled && !invalid) void run() + }} + disabled={disabled || loading} + prepend={error != null ? errorRender({ error }) : undefined} + cancel={ + onCancel && ( + + ) + } + actions={ + + } + > + {children} + + ) +} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/forms/form-card.tsx b/packages/oauth/oauth-provider/src/assets/app/components/forms/form-card.tsx new file mode 100644 index 00000000000..d5da4852c25 --- /dev/null +++ b/packages/oauth/oauth-provider/src/assets/app/components/forms/form-card.tsx @@ -0,0 +1,49 @@ +import { JSX, ReactNode } from 'react' +import { Override } from '../../lib/util.ts' + +export type FormCardProps = Override< + JSX.IntrinsicElements['form'], + { + disabled?: boolean + append?: ReactNode + prepend?: ReactNode + cancel?: ReactNode + actions?: ReactNode + } +> + +export function FormCard({ + actions, + cancel, + append, + children, + prepend, + disabled, + + // form + inert = disabled, + ...props +}: FormCardProps) { + return ( +
+ {prepend &&
{prepend}
} + +
+ {children} +
+ + {append &&
{append}
} + + {(actions || cancel) && ( +
+ {actions} +
+ {cancel} +
+ )} + + ) +} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/forms/input-checkbox.tsx b/packages/oauth/oauth-provider/src/assets/app/components/forms/input-checkbox.tsx new file mode 100644 index 00000000000..5f35a79f16c --- /dev/null +++ b/packages/oauth/oauth-provider/src/assets/app/components/forms/input-checkbox.tsx @@ -0,0 +1,69 @@ +import { JSX, ReactNode, useContext, useMemo, useRef } from 'react' +import { mergeRefs } from '../../lib/ref.ts' +import { Override } from '../../lib/util.ts' +import { FieldsetContext } from './fieldset.tsx' +import { InputContainer } from './input-container.tsx' + +const generateUniqueId = () => Math.random().toString(36).slice(2) + +export type InputCheckboxProps = Override< + Omit< + JSX.IntrinsicElements['input'], + 'className' | 'type' | 'id' | 'children' + >, + { + id?: string + className?: string + children?: ReactNode + } +> + +export function InputCheckbox({ + id, + className, + children, + + // input + ref, + disabled, + 'aria-labelledby': ariaLabelledBy, + ...props +}: InputCheckboxProps) { + const htmlFor = useMemo(generateUniqueId, []) + const containerRef = useRef(null) + const inputRef = useRef(null) + const ctx = useContext(FieldsetContext) + + return ( + + } + tabIndex={-1} + onClick={(event) => { + if (event.target === containerRef.current && !event.defaultPrevented) { + inputRef.current?.click() + inputRef.current?.focus() + } + }} + > + + + ) +} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/forms/input-container.tsx b/packages/oauth/oauth-provider/src/assets/app/components/forms/input-container.tsx new file mode 100644 index 00000000000..f8459d475d3 --- /dev/null +++ b/packages/oauth/oauth-provider/src/assets/app/components/forms/input-container.tsx @@ -0,0 +1,45 @@ +import { useState } from 'react' +import { clsx } from '../../lib/clsx.ts' +import { InputLayout, InputLayoutProps } from './input-layout.tsx' + +export type InputContainerProps = InputLayoutProps + +export function InputContainer({ + className, + icon, + onFocus, + onBlur, + ...props +}: InputContainerProps) { + const [focused, setFocused] = useState(false) + + return ( + { + onFocus?.(event) + if (!event.defaultPrevented) setFocused(true) + }} + onBlur={(event) => { + onBlur?.(event) + if (!event.defaultPrevented) setFocused(false) + }} + icon={ + icon &&
{icon}
+ } + {...props} + /> + ) +} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/forms/input-email-address.tsx b/packages/oauth/oauth-provider/src/assets/app/components/forms/input-email-address.tsx new file mode 100644 index 00000000000..ab2855a1bc3 --- /dev/null +++ b/packages/oauth/oauth-provider/src/assets/app/components/forms/input-email-address.tsx @@ -0,0 +1,66 @@ +import { useLingui } from '@lingui/react/macro' +import { ChangeEvent, useCallback, useState } from 'react' +import { Override } from '../../lib/util.ts' +import { LockIcon } from '../utils/icons.tsx' +import { InputText, InputTextProps } from './input-text.tsx' + +export type InputEmailAddressProps = Override< + Omit, + { + onEmail?: (email: string | undefined) => void + } +> + +export function InputEmailAddress({ + onEmail, + + // InputTextProps + autoCapitalize = 'none', + autoComplete = 'email', + autoCorrect = 'off', + dir = 'auto', + icon = , + onBlur, + onChange, + pattern = '^[^@]+@[^@]+\\.[^@]+$', + spellCheck = 'false', + value, + defaultValue = value, + ...props +}: InputEmailAddressProps) { + const { t } = useLingui() + const [email, setEmail] = useState( + typeof defaultValue === 'string' ? defaultValue : '', + ) + + const doChange = useCallback( + (event: ChangeEvent) => { + const email = event.target.value.toLowerCase() + + setEmail(email) + onChange?.(event) + onEmail?.(event.target.validity.valid ? email : undefined) + }, + [onChange, onEmail], + ) + + return ( + + ) +} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/forms/input-info-card.tsx b/packages/oauth/oauth-provider/src/assets/app/components/forms/input-info-card.tsx new file mode 100644 index 00000000000..83cc56ee9fd --- /dev/null +++ b/packages/oauth/oauth-provider/src/assets/app/components/forms/input-info-card.tsx @@ -0,0 +1,47 @@ +import { memo } from 'react' +import { clsx } from '../../lib/clsx.ts' +import { Override } from '../../lib/util.ts' +import { AlertIcon } from '../utils/icons.tsx' +import { InputLayout, InputLayoutProps } from './input-layout.tsx' + +export type InputInfoCardProps = Override< + Omit, + { + role: 'alert' | 'status' + } +> +export const InputInfoCard = memo(function InputInfoCard({ + role = 'alert', + + // InputLayoutProps + children, + className, + ...props +}: InputInfoCardProps) { + return ( + + } + > +
+ {children} +
+
+ ) +}) diff --git a/packages/oauth/oauth-provider/src/assets/app/components/forms/input-layout.tsx b/packages/oauth/oauth-provider/src/assets/app/components/forms/input-layout.tsx new file mode 100644 index 00000000000..8dd3f2d651b --- /dev/null +++ b/packages/oauth/oauth-provider/src/assets/app/components/forms/input-layout.tsx @@ -0,0 +1,57 @@ +import { JSX, ReactNode } from 'react' +import { clsx } from '../../lib/clsx.ts' +import { Override } from '../../lib/util.ts' + +export type InputLayoutProps = Override< + JSX.IntrinsicElements['div'], + { + icon: ReactNode + append?: ReactNode + } +> + +export function InputLayout({ + icon, + append, + + // HTMLDivElement + className, + children, + ...props +}: InputLayoutProps) { + return ( +
+ {icon && ( +
+ {icon} +
+ )} +
{children}
+ {append && ( +
{append}
+ )} +
+ ) +} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/forms/input-new-password.tsx b/packages/oauth/oauth-provider/src/assets/app/components/forms/input-new-password.tsx new file mode 100644 index 00000000000..64372c75df5 --- /dev/null +++ b/packages/oauth/oauth-provider/src/assets/app/components/forms/input-new-password.tsx @@ -0,0 +1,76 @@ +import { useLingui } from '@lingui/react/macro' +import { ChangeEvent, useCallback, useState } from 'react' +import { MIN_PASSWORD_LENGTH } from '../../lib/password.ts' +import { Override } from '../../lib/util.ts' +import { ExpandTransition } from '../utils/expand-transition.tsx' +import { PasswordStrengthLabel } from '../utils/password-strength-label.tsx' +import { PasswordStrengthMeter } from '../utils/password-strength-meter.tsx' +import { InputPassword, InputPasswordProps } from './input-password.tsx' + +export type InputNewPasswordProps = Override< + Omit, + { + password?: string + onPassword?: (password: undefined | string) => void + } +> + +export function InputNewPassword({ + password: passwordInit = '', + onPassword, + + // InputPasswordProps + onBlur, + onChange, + onFocus, + autoComplete = 'new-password', + minLength = MIN_PASSWORD_LENGTH, + ...props +}: InputNewPasswordProps) { + const { t } = useLingui() + const [focused, setFocused] = useState(false) + const [password, setPassword] = useState(passwordInit) + + const doChange = useCallback( + (event: ChangeEvent) => { + const { value } = event.target + setPassword(value) + onChange?.(event) + onPassword?.(event.target.validity.valid ? value : undefined) + }, + [onChange, onPassword], + ) + + return ( +
+ { + onFocus?.(event) + if (!event.defaultPrevented) setFocused(true) + }} + onBlur={(event) => { + onBlur?.(event) + if (!event.defaultPrevented) setFocused(false) + }} + value={password} + autoComplete={autoComplete} + {...props} + /> + 0} + className="flex flex-col" + > + + + +
+ ) +} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/forms/input-password.tsx b/packages/oauth/oauth-provider/src/assets/app/components/forms/input-password.tsx new file mode 100644 index 00000000000..f9af553f006 --- /dev/null +++ b/packages/oauth/oauth-provider/src/assets/app/components/forms/input-password.tsx @@ -0,0 +1,91 @@ +import { useLingui } from '@lingui/react/macro' +import { ChangeEvent, useCallback, useRef, useState } from 'react' +import { mergeRefs } from '../../lib/ref.ts' +import { Override } from '../../lib/util.ts' +import { LockIcon } from '../utils/icons.tsx' +import { ButtonToggleVisibility } from './button-toggle-visibility.tsx' +import { InputText, InputTextProps } from './input-text.tsx' + +export type InputPasswordProps = Override< + Omit, + { + autoHide?: boolean + } +> + +export function InputPassword({ + autoHide = true, + + // InputTextProps + onBlur, + onChange, + append, + autoComplete = 'current-password', + icon = , + value, + defaultValue = value, + children, + ref, + dir = 'auto', + autoCapitalize = 'none', + autoCorrect = 'off', + spellCheck = 'false', + ...props +}: InputPasswordProps) { + const { t } = useLingui() + const inputRef = useRef(null) + const [visible, setVisible] = useState(false) + const [password, setPassword] = useState( + typeof defaultValue === 'string' ? defaultValue : '', + ) + + const doChange = useCallback( + (event: ChangeEvent) => { + onChange?.(event) + setPassword(event.target.value) + }, + [onChange], + ) + + return ( + { + onBlur?.(event) + if (!event.defaultPrevented) setVisible(false) + } + : onBlur + } + value={password} + onChange={doChange} + type={visible ? 'text' : 'password'} + autoComplete={autoComplete} + append={ + <> + { + setVisible((prev) => !prev) + inputRef.current?.focus() + }} + /> + {append} + + } + > + {children} + + ) +} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/input-text.tsx b/packages/oauth/oauth-provider/src/assets/app/components/forms/input-text.tsx similarity index 52% rename from packages/oauth/oauth-provider/src/assets/app/components/input-text.tsx rename to packages/oauth/oauth-provider/src/assets/app/components/forms/input-text.tsx index fea570f9e03..78eebb5dd12 100644 --- a/packages/oauth/oauth-provider/src/assets/app/components/input-text.tsx +++ b/packages/oauth/oauth-provider/src/assets/app/components/forms/input-text.tsx @@ -1,25 +1,43 @@ import { - forwardRef, - InputHTMLAttributes, + JSX, MouseEventHandler, ReactNode, useCallback, - useImperativeHandle, + useContext, useRef, - useState, } from 'react' -import { InputContainer } from './input-container' +import { mergeRefs } from '../../lib/ref.ts' +import { Override } from '../../lib/util.ts' +import { FieldsetContext } from './fieldset.tsx' +import { InputContainer } from './input-container.tsx' -export const InputText = forwardRef< - HTMLInputElement, +export type InputTextProps = Override< + JSX.IntrinsicElements['input'], { icon?: ReactNode - } & InputHTMLAttributes ->(({ className, icon, children, onFocus, onBlur, ...props }, ref) => { - const [focused, setFocused] = useState(false) - const inputRef = useRef(null) + append?: ReactNode + className?: string + } +> + +export function InputText({ + icon, + append, + className, - useImperativeHandle(ref, () => inputRef.current!, []) + // input + children, + onFocus, + onBlur, + ref, + disabled, + 'aria-labelledby': ariaLabelledBy, + ...props +}: InputTextProps) { + const ctx = useContext(FieldsetContext) + + const inputRef = useRef(null) + const focusedRef = useRef(false) // ref instead of state to avoid re-renders const handleClick = useCallback>( (event) => { @@ -34,36 +52,40 @@ export const InputText = forwardRef< const handleMouseDown = useCallback>( (event) => { - if (focused && event.target !== inputRef.current) { + if (focusedRef.current && event.target !== inputRef.current) { // Prevent "blur" event from firing when clicking outside the input event.preventDefault() event.stopPropagation() } }, - [focused], + [], ) return ( { - setFocused(true) onFocus?.(event) + if (!event.defaultPrevented) focusedRef.current = true }} onBlur={(event) => { - setFocused(false) onBlur?.(event) + if (!event.defaultPrevented) focusedRef.current = false }} - {...props} /> {children} ) -}) +} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/forms/input-token.tsx b/packages/oauth/oauth-provider/src/assets/app/components/forms/input-token.tsx new file mode 100644 index 00000000000..78f6702c7ae --- /dev/null +++ b/packages/oauth/oauth-provider/src/assets/app/components/forms/input-token.tsx @@ -0,0 +1,94 @@ +import { useLingui } from '@lingui/react/macro' +import { ChangeEvent, useState } from 'react' +import { Override } from '../../lib/util.ts' +import { TokenIcon } from '../utils/icons.tsx' +import { InputText, InputTextProps } from './input-text.tsx' + +export type InputTokenProps = Override< + Omit< + InputTextProps, + | 'type' + | 'pattern' + | 'autoCapitalize' + | 'autoCorrect' + | 'autoComplete' + | 'spellCheck' + | 'minLength' + | 'maxLength' + | 'placeholder' + | 'dir' + >, + { + example?: string + onToken?: (code: string | null) => void + } +> + +export const OTP_CODE_EXAMPLE = 'XXXXX-XXXXX' + +export function InputToken({ + example = OTP_CODE_EXAMPLE, + onToken, + + // InputTextProps + icon = , + title = example, + onChange, + value, + defaultValue = value, + ...props +}: InputTokenProps) { + const { t } = useLingui() + const [token, setToken] = useState( + typeof defaultValue === 'string' ? defaultValue : '', + ) + + return ( + ) => { + const { value, selectionEnd, selectionStart } = event.currentTarget + + const fixedValue = fix(value) + + event.currentTarget.value = fixedValue + + // Move the cursor back where it was relative to the original value + const pos = selectionEnd ?? selectionStart + if (pos != null) { + const fixedSlicedValue = fix(value.slice(0, pos)) + event.currentTarget.selectionStart = + event.currentTarget.selectionEnd = fixedSlicedValue.length + } + + setToken(fixedValue) + onChange?.(event) + + if (!event.isDefaultPrevented()) { + onToken?.(fixedValue.length === 11 ? fixedValue : null) + } + }} + /> + ) +} + +function fix(value: string) { + const normalized = value.toUpperCase().replaceAll(/[^A-Z2-7]/g, '') + + if (normalized.length <= 5) return normalized + + return `${normalized.slice(0, 5)}-${normalized.slice(5, 10)}` +} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/forms/wizard-card.tsx b/packages/oauth/oauth-provider/src/assets/app/components/forms/wizard-card.tsx new file mode 100644 index 00000000000..f9b694ce06d --- /dev/null +++ b/packages/oauth/oauth-provider/src/assets/app/components/forms/wizard-card.tsx @@ -0,0 +1,104 @@ +import { Trans } from '@lingui/react/macro' +import { JSX, ReactNode } from 'react' +import { DisabledStep, Step, useStepper } from '../../hooks/use-stepper.ts' +import { clsx } from '../../lib/clsx.ts' +import { Override } from '../../lib/util.ts' + +export type DoneFn = (...a: any) => unknown + +export type WizardSlotData = { + invalid: boolean + + prev?: () => void + prevLabel: ReactNode + + // On the last step, the "next()" function will actually be the done function + next: (() => void) | TDone + nextLabel: ReactNode +} + +export type WizardRenderFn = ( + data: WizardSlotData, +) => ReactNode + +export type WizardStep = Step & { + titleRender?: WizardRenderFn + contentRender: WizardRenderFn +} + +export type WizardCardProps = Override< + Omit, + { + prevLabel?: ReactNode + nextLabel?: ReactNode + + onBack?: () => void + backLabel?: ReactNode + + onDone: TDone + doneLabel?: ReactNode + + steps: readonly (WizardStep | DisabledStep)[] + } +> + +export function WizardCard({ + prevLabel, + nextLabel, + + onBack, + backLabel, + + onDone, + doneLabel, + + steps, + className, + + ...props +}: WizardCardProps) { + const { + atFirst, + atLast, + count, + current, + currentPosition, + isCompleted, + toNext, + toPrev, + toRequired, + } = useStepper(steps) + + const data: WizardSlotData = { + invalid: current?.invalid || false, + + prevLabel: (atFirst && backLabel) || prevLabel || Back, + prev: atFirst ? onBack : toPrev, + + nextLabel: (atLast && doneLabel) || nextLabel || Next, + next: + atLast && isCompleted + ? onDone + : () => { + // If already at last step, go to the first incomplete (required) step + if (!toNext()) toRequired() + }, + } + + const stepTitle = current?.titleRender?.(data) + const stepContent = current?.contentRender?.(data) + + return ( +
+

+ + Step {currentPosition} of {count} + +

+ + {stepTitle &&

{stepTitle}

} + + {stepContent} +
+ ) +} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/help-card.tsx b/packages/oauth/oauth-provider/src/assets/app/components/help-card.tsx deleted file mode 100644 index f71b6f47e97..00000000000 --- a/packages/oauth/oauth-provider/src/assets/app/components/help-card.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { HTMLAttributes } from 'react' -import { LinkDefinition } from '../backend-data' -import { clsx } from '../lib/clsx' - -export type HelpCardProps = { - links?: readonly LinkDefinition[] -} - -export function HelpCard({ - links, - - className, - ...attrs -}: HelpCardProps & - Omit< - HTMLAttributes, - keyof HelpCardProps | 'children' - >) { - const helpLink = links?.find((l) => l.rel === 'help') - - if (!helpLink) return null - - return ( -

- Having trouble?{' '} - - Contact {helpLink.title} - -

- ) -} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/icons/alert-icon.tsx b/packages/oauth/oauth-provider/src/assets/app/components/icons/alert-icon.tsx deleted file mode 100644 index ee3c840b5db..00000000000 --- a/packages/oauth/oauth-provider/src/assets/app/components/icons/alert-icon.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { makeSvgComponent } from './util' - -export const AlertIcon = makeSvgComponent( - 'M11.14 4.494a.995.995 0 0 1 1.72 0l7.001 12.008a.996.996 0 0 1-.86 1.498H4.999a.996.996 0 0 1-.86-1.498L11.14 4.494Zm3.447-1.007c-1.155-1.983-4.019-1.983-5.174 0L2.41 15.494C1.247 17.491 2.686 20 4.998 20h14.004c2.312 0 3.751-2.509 2.587-4.506L14.587 3.487ZM13 9.019a1 1 0 1 0-2 0v2.994a1 1 0 1 0 2 0V9.02Zm-1 4.731a1.25 1.25 0 1 0 0 2.5 1.25 1.25 0 0 0 0-2.5Z', -) diff --git a/packages/oauth/oauth-provider/src/assets/app/components/icons/at-symbol-icon.tsx b/packages/oauth/oauth-provider/src/assets/app/components/icons/at-symbol-icon.tsx deleted file mode 100644 index 5410dbe7a65..00000000000 --- a/packages/oauth/oauth-provider/src/assets/app/components/icons/at-symbol-icon.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { makeSvgComponent } from './util' - -export const AtSymbolIcon = makeSvgComponent( - 'M12 4a8 8 0 1 0 4.21 14.804 1 1 0 0 1 1.054 1.7A9.958 9.958 0 0 1 12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10c0 1.104-.27 2.31-.949 3.243-.716.984-1.849 1.6-3.331 1.465a4.207 4.207 0 0 1-2.93-1.585c-.94 1.21-2.388 1.94-3.985 1.715-2.53-.356-4.04-2.91-3.682-5.458.358-2.547 2.514-4.586 5.044-4.23.905.127 1.68.536 2.286 1.126a1 1 0 0 1 1.964.368l-.515 3.545v.002a2.222 2.222 0 0 0 1.999 2.526c.75.068 1.212-.21 1.533-.65.358-.493.566-1.245.566-2.067a8 8 0 0 0-8-8Zm-.112 5.13c-1.195-.168-2.544.819-2.784 2.529-.24 1.71.784 3.03 1.98 3.198 1.195.168 2.543-.819 2.784-2.529.24-1.71-.784-3.03-1.98-3.198Z', -) diff --git a/packages/oauth/oauth-provider/src/assets/app/components/icons/caret-right-icon.tsx b/packages/oauth/oauth-provider/src/assets/app/components/icons/caret-right-icon.tsx deleted file mode 100644 index fe8b62e807d..00000000000 --- a/packages/oauth/oauth-provider/src/assets/app/components/icons/caret-right-icon.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { makeSvgComponent } from './util' - -export const CaretRightIcon = makeSvgComponent( - 'M8.293 3.293a1 1 0 0 1 1.414 0l8 8a1 1 0 0 1 0 1.414l-8 8a1 1 0 0 1-1.414-1.414L15.586 12 8.293 4.707a1 1 0 0 1 0-1.414Z', -) diff --git a/packages/oauth/oauth-provider/src/assets/app/components/icons/lock-icon.tsx b/packages/oauth/oauth-provider/src/assets/app/components/icons/lock-icon.tsx deleted file mode 100644 index 135ecc9d910..00000000000 --- a/packages/oauth/oauth-provider/src/assets/app/components/icons/lock-icon.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { makeSvgComponent } from './util' - -export const LockIcon = makeSvgComponent( - 'M7 7a5 5 0 0 1 10 0v2h1a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-9a2 2 0 0 1 2-2h1V7Zm-1 4v9h12v-9H6Zm9-2H9V7a3 3 0 1 1 6 0v2Zm-3 4a1 1 0 0 1 1 1v3a1 1 0 1 1-2 0v-3a1 1 0 0 1 1-1Z', -) diff --git a/packages/oauth/oauth-provider/src/assets/app/components/icons/token-icon.tsx b/packages/oauth/oauth-provider/src/assets/app/components/icons/token-icon.tsx deleted file mode 100644 index b7f57c0e303..00000000000 --- a/packages/oauth/oauth-provider/src/assets/app/components/icons/token-icon.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { makeSvgComponent } from './util' - -export const TokenIcon = makeSvgComponent( - 'M4 5.5a.5.5 0 0 0-.5.5v2.535a.5.5 0 0 0 .25.433A3.498 3.498 0 0 1 5.5 12a3.498 3.498 0 0 1-1.75 3.032.5.5 0 0 0-.25.433V18a.5.5 0 0 0 .5.5h16a.5.5 0 0 0 .5-.5v-2.535a.5.5 0 0 0-.25-.433A3.498 3.498 0 0 1 18.5 12a3.5 3.5 0 0 1 1.75-3.032.5.5 0 0 0 .25-.433V6a.5.5 0 0 0-.5-.5H4ZM2.5 6A1.5 1.5 0 0 1 4 4.5h16A1.5 1.5 0 0 1 21.5 6v3.17a.5.5 0 0 1-.333.472 2.501 2.501 0 0 0 0 4.716.5.5 0 0 1 .333.471V18a1.5 1.5 0 0 1-1.5 1.5H4A1.5 1.5 0 0 1 2.5 18v-3.17a.5.5 0 0 1 .333-.472 2.501 2.501 0 0 0 0-4.716.5.5 0 0 1-.333-.471V6Zm12 2a.5.5 0 1 1 1 0 .5.5 0 0 1-1 0Zm0 4a.5.5 0 1 1 1 0 .5.5 0 0 1-1 0Zm0 4a.5.5 0 1 1 1 0 .5.5 0 0 1-1 0Z', -) diff --git a/packages/oauth/oauth-provider/src/assets/app/components/icons/util.tsx b/packages/oauth/oauth-provider/src/assets/app/components/icons/util.tsx deleted file mode 100644 index 9ef11cde1f1..00000000000 --- a/packages/oauth/oauth-provider/src/assets/app/components/icons/util.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import type { SVGProps } from 'react' - -export const makeSvgComponent = (path: string) => - function ( - props: Omit, 'viewBox' | 'children' | 'xmlns'>, - ) { - return ( - - - - ) - } diff --git a/packages/oauth/oauth-provider/src/assets/app/components/info-card.tsx b/packages/oauth/oauth-provider/src/assets/app/components/info-card.tsx deleted file mode 100644 index 69c2fa6af12..00000000000 --- a/packages/oauth/oauth-provider/src/assets/app/components/info-card.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { clsx } from '../lib/clsx' -import { Override } from '../lib/util' -import { AlertIcon } from './icons/alert-icon' -import { InputLayout, InputLayoutProps } from './input-layout' - -export type InfoCardProps = Override< - InputLayoutProps, - { - role: 'alert' | 'status' - } -> - -export function InfoCard({ - children, - className, - role = 'alert', - ...props -}: InfoCardProps) { - return ( - - } - {...props} - > -
- {children} -
-
- ) -} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/input-checkbox.tsx b/packages/oauth/oauth-provider/src/assets/app/components/input-checkbox.tsx deleted file mode 100644 index 3bda701ff43..00000000000 --- a/packages/oauth/oauth-provider/src/assets/app/components/input-checkbox.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { InputHTMLAttributes, useRef, useState } from 'react' -import { InputContainer } from './input-container' - -const generateUniqueId = () => Math.random().toString(36).slice(2) - -export type InputCheckboxProps = Omit< - InputHTMLAttributes, - 'type' -> - -export function InputCheckbox({ - id, - children, - className, - ...props -}: InputCheckboxProps) { - const [htmlFor] = useState(generateUniqueId) - const ref = useRef(null) - const inputRef = useRef(null) - - return ( - - } - className={className} - onClick={(event) => { - if (event.target === ref.current && !event.defaultPrevented) { - inputRef.current?.click() - inputRef.current?.focus() - } - }} - > - - - ) -} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/input-container.tsx b/packages/oauth/oauth-provider/src/assets/app/components/input-container.tsx deleted file mode 100644 index dc4165260c6..00000000000 --- a/packages/oauth/oauth-provider/src/assets/app/components/input-container.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { forwardRef, useState } from 'react' -import { clsx } from '../lib/clsx' -import { InputLayout, InputLayoutProps } from './input-layout' - -export type InputContainerProps = InputLayoutProps - -export const InputContainer = forwardRef( - ({ className, onFocus, icon, onBlur, ...props }, ref) => { - const [focused, setFocused] = useState(false) - - return ( - { - onFocus?.(event) - if (!event.defaultPrevented) setFocused(true) - }} - onBlur={(event) => { - onBlur?.(event) - if (!event.defaultPrevented) setFocused(false) - }} - icon={
{icon}
} - {...props} - /> - ) - }, -) diff --git a/packages/oauth/oauth-provider/src/assets/app/components/input-layout.tsx b/packages/oauth/oauth-provider/src/assets/app/components/input-layout.tsx deleted file mode 100644 index 686f0ab7962..00000000000 --- a/packages/oauth/oauth-provider/src/assets/app/components/input-layout.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { forwardRef, HTMLAttributes, ReactNode } from 'react' -import { clsx } from '../lib/clsx' -import { Override } from '../lib/util' - -export type InputLayoutProps = Override< - HTMLAttributes, - { - icon?: ReactNode - append?: ReactNode - } -> - -export const InputLayout = forwardRef( - ({ className, icon, append, children, ...props }, ref) => { - return ( -
-
- {icon} -
-
{children}
- {append &&
{append}
} -
- ) - }, -) diff --git a/packages/oauth/oauth-provider/src/assets/app/components/layout-title-page.tsx b/packages/oauth/oauth-provider/src/assets/app/components/layouts/layout-title-page.tsx similarity index 79% rename from packages/oauth/oauth-provider/src/assets/app/components/layout-title-page.tsx rename to packages/oauth/oauth-provider/src/assets/app/components/layouts/layout-title-page.tsx index a68b597d499..e83537b0e94 100644 --- a/packages/oauth/oauth-provider/src/assets/app/components/layout-title-page.tsx +++ b/packages/oauth/oauth-provider/src/assets/app/components/layouts/layout-title-page.tsx @@ -1,12 +1,13 @@ -import { HTMLAttributes, ReactNode } from 'react' -import { clsx } from '../lib/clsx' -import { Override } from '../lib/util' +import { JSX, ReactNode } from 'react' +import { clsx } from '../../lib/clsx.ts' +import { Override } from '../../lib/util.ts' export type LayoutTitlePageProps = Override< - HTMLAttributes, + JSX.IntrinsicElements['div'], { title?: ReactNode subtitle?: ReactNode + children?: ReactNode } > @@ -14,6 +15,8 @@ export function LayoutTitlePage({ children, title, subtitle, + + // HTMLDivElement className, ...props }: LayoutTitlePageProps) { @@ -29,6 +32,8 @@ export function LayoutTitlePage({ 'dark:bg-slate-900 dark:text-slate-100', )} > + {title && {title}} +
+

{subtitle}

)} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/layout-welcome.tsx b/packages/oauth/oauth-provider/src/assets/app/components/layouts/layout-welcome.tsx similarity index 71% rename from packages/oauth/oauth-provider/src/assets/app/components/layout-welcome.tsx rename to packages/oauth/oauth-provider/src/assets/app/components/layouts/layout-welcome.tsx index 0e1f8189ebf..1ef2a74a064 100644 --- a/packages/oauth/oauth-provider/src/assets/app/components/layout-welcome.tsx +++ b/packages/oauth/oauth-provider/src/assets/app/components/layouts/layout-welcome.tsx @@ -1,32 +1,28 @@ -import { HTMLAttributes } from 'react' -import { Override } from '../lib/util' -import { clsx } from '../lib/clsx' +import { JSX, ReactNode } from 'react' +import { CustomizationData } from '../../backend-types.ts' +import { clsx } from '../../lib/clsx.ts' +import { Override } from '../../lib/util.ts' export type LayoutWelcomeProps = Override< - HTMLAttributes, + JSX.IntrinsicElements['div'], { - name?: string - logo?: string - links?: Array<{ - title: string - href: string - rel?: string - }> - logoAlt?: string + customizationData: CustomizationData | undefined + title?: ReactNode } > export function LayoutWelcome({ - name, - logo, - logoAlt = name || 'Logo', - links, - children, + customizationData: { logo, name, links } = {}, + title = name, + + // div className, + children, ...props }: LayoutWelcomeProps) { return (
-
+ {title && {title}} + +
{logo && ( {logoAlt} )} @@ -58,6 +56,7 @@ export function LayoutWelcome({
) diff --git a/packages/oauth/oauth-provider/src/assets/app/components/utils/error-message.tsx b/packages/oauth/oauth-provider/src/assets/app/components/utils/error-message.tsx index 8bd645b2fd8..06b070f2349 100644 --- a/packages/oauth/oauth-provider/src/assets/app/components/utils/error-message.tsx +++ b/packages/oauth/oauth-provider/src/assets/app/components/utils/error-message.tsx @@ -1,6 +1,7 @@ import { Trans } from '@lingui/react/macro' import { ReactNode, memo } from 'react' import { + EmailTakenError, HandleUnavailableError, InvalidCredentialsError, RequestExpiredError, @@ -20,6 +21,10 @@ export const ErrorMessage = memo(function ErrorMessage({ return Wrong identifier or password } + if (error instanceof EmailTakenError) { + return This email is already used + } + if (error instanceof HandleUnavailableError) { switch (error.reason) { case 'syntax': diff --git a/packages/oauth/oauth-provider/src/assets/app/lib/api.ts b/packages/oauth/oauth-provider/src/assets/app/lib/api.ts index 96a998ad77e..fbe8fa40ebd 100644 --- a/packages/oauth/oauth-provider/src/assets/app/lib/api.ts +++ b/packages/oauth/oauth-provider/src/assets/app/lib/api.ts @@ -97,6 +97,9 @@ export class Api extends JsonClient<{ if (HandleUnavailableError.is(json)) { return new HandleUnavailableError(json) } + if (EmailTakenError.is(json)) { + return new EmailTakenError(json) + } if (RequestExpiredError.is(json)) { return new RequestExpiredError(json) } @@ -182,6 +185,16 @@ export class UnknownRequestUriError< return super.is(json) && json.error_description === 'Unknown request_uri' } } +export type EmailTakenPayload = InvalidRequestPayload & { + error_description: 'Email already taken' +} +export class EmailTakenError< + P extends EmailTakenPayload = EmailTakenPayload, +> extends InvalidRequestError

{ + static is(json: unknown): json is EmailTakenPayload { + return super.is(json) && json.error_description === 'Email already taken' + } +} export type HandleUnavailablePayload = JsonErrorPayload<'handle_unavailable'> & { diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/an/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/an/messages.po index 7777f9d53ab..b6a6c56612d 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/an/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/an/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/ast/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/ast/messages.po index 6a3fcb845f4..78b990aaf2f 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/ast/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/ast/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/ca/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/ca/messages.po index 5e65d34df86..a312d84b43e 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/ca/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/ca/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/da/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/da/messages.po index 072dfc1b654..349eea6c3b6 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/da/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/da/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/de/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/de/messages.po index 7acd58ca7a8..d9283c1837f 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/de/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/de/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/el/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/el/messages.po index aa97663ca6f..ece2433d87c 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/el/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/el/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/en-GB/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/en-GB/messages.po index 829afa81427..b30480f64ed 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/en-GB/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/en-GB/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/en/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/en/messages.po index ecb388f2ccc..d6d8478b58c 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/en/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/en/messages.po @@ -26,7 +26,7 @@ msgstr "<0/> is asking for permission to access your account (<1/>)." msgid "2FA Confirmation" msgstr "2FA Confirmation" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "A second authentication factor is required" @@ -50,7 +50,7 @@ msgstr "Already have a code?" msgid "An application on your device" msgstr "An application on your device" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "An unknown error occurred" @@ -365,31 +365,35 @@ msgstr "Support" msgid "Terms of Service" msgstr "Terms of Service" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "That handle cannot be used" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "The domain name is not allowed" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "The handle contains inappropriate language" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "The handle is already in use" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "The handle is invalid" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "This email is already used" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "This handle is reserved" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "This sign-in session has expired" @@ -404,7 +408,7 @@ msgstr "Too short" msgid "Type your desired username" msgstr "Type your desired username" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "Unexpected server response" @@ -441,7 +445,7 @@ msgstr "We're so excited to have you join us!" msgid "Weak" msgstr "Weak" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "Wrong identifier or password" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/es/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/es/messages.po index e12d6701d4f..f8165865656 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/es/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/es/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/eu/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/eu/messages.po index 7249b5be381..e6adeb86cc0 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/eu/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/eu/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/fi/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/fi/messages.po index b76ed22ea08..b07562f7a43 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/fi/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/fi/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/fr/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/fr/messages.po index a5ee4230158..85790ebbcf8 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/fr/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/fr/messages.po @@ -26,7 +26,7 @@ msgstr "<0/> demande la permission d'accéder à votre compte (<1/>)." msgid "2FA Confirmation" msgstr "Confirmation 2FA" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "Un second facteur d'authentification est requis" @@ -50,7 +50,7 @@ msgstr "Vous avez déjà un code ?" msgid "An application on your device" msgstr "Une application sur votre appareil" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "Une erreur inconnue s'est produite" @@ -365,31 +365,35 @@ msgstr "Support" msgid "Terms of Service" msgstr "Conditions d'Utilisation" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "Ce pseudonyme ne peut pas être utilisé" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "Le nom de domaine n'est pas autorisé" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "Le pseudonyme contient un langage inapproprié" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "Ce pseudonyme est déjà utilisé" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "Le pseudonyme est invalide" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "Cet email est déjà utilisé" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "Ce pseudonyme est réservé" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "Cette session de connexion a expiré" @@ -404,7 +408,7 @@ msgstr "Trop court" msgid "Type your desired username" msgstr "Saisissez le nom d'utilisateur souhaité" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "Réponse inattendue du serveur" @@ -441,7 +445,7 @@ msgstr "Nous sommes ravis de vous accueillir parmi nous !" msgid "Weak" msgstr "Faible" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "Identifiant ou mot de passe incorrect" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/ga/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/ga/messages.po index b867da30105..662b70a06da 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/ga/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/ga/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/gl/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/gl/messages.po index 6e6758ff249..ea21131b920 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/gl/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/gl/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/hi/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/hi/messages.po index 464af584344..8df6f5d5f05 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/hi/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/hi/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/hu/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/hu/messages.po index 4a2cd2d182b..357c7c2533a 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/hu/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/hu/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/ia/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/ia/messages.po index 5080f3cf038..f031a94ee68 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/ia/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/ia/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/id/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/id/messages.po index 21dbccb1c7a..66d8150606e 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/id/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/id/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/it/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/it/messages.po index 48fc7ee4d80..1baf6ede2dc 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/it/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/it/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/ja/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/ja/messages.po index ec2e0748c82..30408af4ccf 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/ja/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/ja/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/km/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/km/messages.po index 22434480788..0c4d10fa029 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/km/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/km/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/ko/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/ko/messages.po index d67d4264b52..bf58047587e 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/ko/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/ko/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/ne/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/ne/messages.po index edf75640646..bdc7f9e7420 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/ne/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/ne/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/nl/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/nl/messages.po index 33ba0520de3..fd3a5fcc124 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/nl/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/nl/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/pl/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/pl/messages.po index 1a2e91059f8..bb74974a482 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/pl/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/pl/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/pt-BR/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/pt-BR/messages.po index f82f46a5ddd..e2e847cea9b 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/pt-BR/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/pt-BR/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/ro/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/ro/messages.po index f15ac44ed12..4d88dedc363 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/ro/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/ro/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/ru/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/ru/messages.po index a414fe2c8c9..81341aa7fc4 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/ru/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/ru/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/sv/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/sv/messages.po index b18225de3ce..2ccf2f30062 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/sv/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/sv/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/th/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/th/messages.po index a00c54d7866..9ec65ffe33e 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/th/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/th/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/tr/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/tr/messages.po index f3bba498ecd..4e0a6a7389a 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/tr/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/tr/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/uk/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/uk/messages.po index 2bae7d184ac..beeea44f28e 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/uk/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/uk/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/vi/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/vi/messages.po index 671e9f5f626..ef080fe8009 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/vi/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/vi/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/zh-CN/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/zh-CN/messages.po index 95ded3f7500..02522951020 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/zh-CN/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/zh-CN/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/zh-HK/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/zh-HK/messages.po index 00f4786d86f..50022e3b626 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/zh-HK/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/zh-HK/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/oauth/oauth-provider/src/assets/app/locales/zh-TW/messages.po b/packages/oauth/oauth-provider/src/assets/app/locales/zh-TW/messages.po index 7995b36681b..e1f78650703 100644 --- a/packages/oauth/oauth-provider/src/assets/app/locales/zh-TW/messages.po +++ b/packages/oauth/oauth-provider/src/assets/app/locales/zh-TW/messages.po @@ -26,7 +26,7 @@ msgstr "" msgid "2FA Confirmation" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:42 +#: src/assets/app/components/utils/error-message.tsx:47 msgid "A second authentication factor is required" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "An application on your device" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:56 +#: src/assets/app/components/utils/error-message.tsx:61 msgid "An unknown error occurred" msgstr "" @@ -365,31 +365,35 @@ msgstr "" msgid "Terms of Service" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:37 +#: src/assets/app/components/utils/error-message.tsx:42 msgid "That handle cannot be used" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:28 +#: src/assets/app/components/utils/error-message.tsx:33 msgid "The domain name is not allowed" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:30 +#: src/assets/app/components/utils/error-message.tsx:35 msgid "The handle contains inappropriate language" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:35 +#: src/assets/app/components/utils/error-message.tsx:40 msgid "The handle is already in use" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:26 +#: src/assets/app/components/utils/error-message.tsx:31 msgid "The handle is invalid" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:33 +#: src/assets/app/components/utils/error-message.tsx:25 +msgid "This email is already used" +msgstr "" + +#: src/assets/app/components/utils/error-message.tsx:38 msgid "This handle is reserved" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:49 +#: src/assets/app/components/utils/error-message.tsx:54 msgid "This sign-in session has expired" msgstr "" @@ -404,7 +408,7 @@ msgstr "" msgid "Type your desired username" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:53 +#: src/assets/app/components/utils/error-message.tsx:58 msgid "Unexpected server response" msgstr "" @@ -441,7 +445,7 @@ msgstr "" msgid "Weak" msgstr "" -#: src/assets/app/components/utils/error-message.tsx:20 +#: src/assets/app/components/utils/error-message.tsx:21 msgid "Wrong identifier or password" msgstr "" diff --git a/packages/pds/src/account-manager/oauth-store.ts b/packages/pds/src/account-manager/oauth-store.ts index f34a2ec96d3..e756f275ce9 100644 --- a/packages/pds/src/account-manager/oauth-store.ts +++ b/packages/pds/src/account-manager/oauth-store.ts @@ -109,7 +109,7 @@ export class OAuthStore }) if (account) { - throw new InvalidRequestError(`Email already taken: ${email}`) + throw new InvalidRequestError(`Email already taken`) } } From 283504aaf56478a0c35591a8a8aa8974b23bde39 Mon Sep 17 00:00:00 2001 From: Matthieu Sieben Date: Wed, 5 Mar 2025 21:35:04 +0100 Subject: [PATCH 51/90] minor margin adaptations --- .../src/assets/app/components/forms/form-card.tsx | 2 +- .../src/assets/app/components/forms/wizard-card.tsx | 2 +- .../src/assets/app/components/layouts/layout-title-page.tsx | 2 +- .../src/assets/app/components/layouts/layout-welcome.tsx | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/oauth/oauth-provider/src/assets/app/components/forms/form-card.tsx b/packages/oauth/oauth-provider/src/assets/app/components/forms/form-card.tsx index d5da4852c25..6ef610507dd 100644 --- a/packages/oauth/oauth-provider/src/assets/app/components/forms/form-card.tsx +++ b/packages/oauth/oauth-provider/src/assets/app/components/forms/form-card.tsx @@ -25,7 +25,7 @@ export function FormCard({ ...props }: FormCardProps) { return ( -

+ {prepend &&
{prepend}
}
diff --git a/packages/oauth/oauth-provider/src/assets/app/components/forms/wizard-card.tsx b/packages/oauth/oauth-provider/src/assets/app/components/forms/wizard-card.tsx index 43cee74b7f5..3ed6727ca72 100644 --- a/packages/oauth/oauth-provider/src/assets/app/components/forms/wizard-card.tsx +++ b/packages/oauth/oauth-provider/src/assets/app/components/forms/wizard-card.tsx @@ -102,7 +102,7 @@ export function WizardCard({ return (
-

+

Step {currentPosition} of {count} diff --git a/packages/oauth/oauth-provider/src/assets/app/components/layouts/layout-title-page.tsx b/packages/oauth/oauth-provider/src/assets/app/components/layouts/layout-title-page.tsx index a4f5191d1d6..f612cc26523 100644 --- a/packages/oauth/oauth-provider/src/assets/app/components/layouts/layout-title-page.tsx +++ b/packages/oauth/oauth-provider/src/assets/app/components/layouts/layout-title-page.tsx @@ -71,7 +71,7 @@ export function LayoutTitlePage({

-
{children}
+
{children}
) } diff --git a/packages/oauth/oauth-provider/src/assets/app/components/layouts/layout-welcome.tsx b/packages/oauth/oauth-provider/src/assets/app/components/layouts/layout-welcome.tsx index 942895820e4..c8fde45d363 100644 --- a/packages/oauth/oauth-provider/src/assets/app/components/layouts/layout-welcome.tsx +++ b/packages/oauth/oauth-provider/src/assets/app/components/layouts/layout-welcome.tsx @@ -35,7 +35,7 @@ export function LayoutWelcome({ > {title && {title}} -
+
{logo && ( -
) }) diff --git a/packages/oauth/oauth-provider/src/assets/app/views/authorize/sign-up/sign-up-handle-form.tsx b/packages/oauth/oauth-provider/src/assets/app/views/authorize/sign-up/sign-up-handle-form.tsx index 2d6111e7b70..e926c110f9d 100644 --- a/packages/oauth/oauth-provider/src/assets/app/views/authorize/sign-up/sign-up-handle-form.tsx +++ b/packages/oauth/oauth-provider/src/assets/app/views/authorize/sign-up/sign-up-handle-form.tsx @@ -13,9 +13,10 @@ import { CheckMarkIcon, XMarkIcon, } from '../../../components/utils/icons.tsx' -import { clsx } from '../../../lib/clsx.ts' +import { clsx, cx } from '../../../lib/clsx.ts' import { mergeRefs } from '../../../lib/ref.ts' import { Override } from '../../../lib/util.ts' +import { Admonition } from '../../../components/utils/admonition.tsx' /** * Spec limit is 63, but in practice, we've limited it to 18 in our implementations. @@ -150,102 +151,131 @@ export function SignUpHandleForm({ append={children} >
Type your desired username}> - } - name="handle" - type="text" - placeholder={t`Type your desired username`} - aria-label={t`Type your desired username`} - title={t`Type your desired username`} - append={ - domains.length > 1 && ( - - ) - } - pattern="[a-z0-9][a-z0-9\-]+[a-z0-9]" - minLength={minLength} - maxLength={maxLength} - autoCapitalize="none" - autoCorrect="off" - autoComplete="off" - dir="auto" - enterKeyHint="done" - autoFocus - required - value={segment} - onChange={(event) => { - const segment = event.target.value.toLowerCase() - - // Ensure the input is always lowercase - const selectionStart = event.target.selectionStart - const selectionEnd = event.target.selectionEnd - event.target.value = segment - event.target.setSelectionRange(selectionStart, selectionEnd) - - setSegment(segment) - }} - /> -
- - -
- - Only contains letters, numbers, and hyphens - - +
+ } + name="handle" + type="text" + placeholder={t`Type your desired username`} + aria-label={t`Type your desired username`} + title={t`Type your desired username`} + append={ + domains.length > 1 && ( + + ) + } + pattern="[a-z0-9][a-z0-9\-]+[a-z0-9]" + minLength={minLength} + maxLength={maxLength} + autoCapitalize="none" + autoCorrect="off" + autoComplete="off" + dir="auto" + enterKeyHint="done" + autoFocus + required + value={segment} + onChange={(event) => { + const segment = event.target.value.toLowerCase() + + // Ensure the input is always lowercase + const selectionStart = event.target.selectionStart + const selectionEnd = event.target.selectionEnd + event.target.value = segment + event.target.setSelectionRange(selectionStart, selectionEnd) + + setSegment(segment) + }} + /> + +

- Between {minLength} and {maxLength} characters + Your full username will be:{' '} + {segment.length ? ( + + {preview} + + ) : ( +

+ )} - +

+ - -

- - Your full username will be {preview} - -

-
+
+ + Only contains letters, numbers, and hyphens + + + + Between {minLength} and {maxLength} characters + + +
-

+ +

You can change this username to any domain name you control after your account is set up.

- + ) } type ValidationMessageProps = JSX.IntrinsicElements['div'] & { valid: boolean + hasValue: boolean } function ValidationMessage({ valid, + hasValue, // div children, @@ -253,19 +283,27 @@ function ValidationMessage({ }: ValidationMessageProps) { const { t } = useLingui() return ( -
- {valid ? ( - +
+ {hasValue ? ( + <> + {valid ? ( + + ) : ( + + )} + ) : ( - +
+
+
)} - {children} +
{children}
) } From 7c763d7e01f46b53f567e7a8c51742da0322316f Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Thu, 6 Mar 2025 10:07:42 -0600 Subject: [PATCH 67/90] Tweak reset flows --- .../components/forms/input-new-password.tsx | 4 +-- .../app/components/utils/admonition.tsx | 28 +++++++++++++------ .../reset-password-confirm-form.tsx | 15 ++++++---- .../reset-password-request-form.tsx | 15 ++++++---- .../reset-password/reset-password-view.tsx | 6 ++-- 5 files changed, 42 insertions(+), 26 deletions(-) diff --git a/packages/oauth/oauth-provider/src/assets/app/components/forms/input-new-password.tsx b/packages/oauth/oauth-provider/src/assets/app/components/forms/input-new-password.tsx index 64372c75df5..c648b665815 100644 --- a/packages/oauth/oauth-provider/src/assets/app/components/forms/input-new-password.tsx +++ b/packages/oauth/oauth-provider/src/assets/app/components/forms/input-new-password.tsx @@ -65,9 +65,9 @@ export function InputNewPassword({ visible={focused && password.length > 0} className="flex flex-col" > - + diff --git a/packages/oauth/oauth-provider/src/assets/app/components/utils/admonition.tsx b/packages/oauth/oauth-provider/src/assets/app/components/utils/admonition.tsx index d293a58c060..c4ab888fc55 100644 --- a/packages/oauth/oauth-provider/src/assets/app/components/utils/admonition.tsx +++ b/packages/oauth/oauth-provider/src/assets/app/components/utils/admonition.tsx @@ -1,12 +1,12 @@ import { memo, JSX } from 'react' import { clsx, cx } from '../../lib/clsx.ts' import { Override } from '../../lib/util.ts' -import { AlertIcon } from './icons.tsx' +import { AlertIcon, EyeIcon } from './icons.tsx' export type Props = Override< JSX.IntrinsicElements['div'], { - role: 'alert' | 'status' + role: 'alert' | 'status' | 'info' } > @@ -31,13 +31,23 @@ export const Admonition = memo(function Admonition({ className, ])} > - + {role === 'info' ? ( + + ) : ( + + )}
{children}
diff --git a/packages/oauth/oauth-provider/src/assets/app/views/authorize/reset-password/reset-password-confirm-form.tsx b/packages/oauth/oauth-provider/src/assets/app/views/authorize/reset-password/reset-password-confirm-form.tsx index 1e929517044..0b0a63620bc 100644 --- a/packages/oauth/oauth-provider/src/assets/app/views/authorize/reset-password/reset-password-confirm-form.tsx +++ b/packages/oauth/oauth-provider/src/assets/app/views/authorize/reset-password/reset-password-confirm-form.tsx @@ -7,6 +7,7 @@ import { } from '../../../components/forms/form-card-async.tsx' import { InputNewPassword } from '../../../components/forms/input-new-password.tsx' import { InputToken } from '../../../components/forms/input-token.tsx' +import { Admonition } from '../../../components/utils/admonition.tsx' import { useRandomString } from '../../../hooks/use-random-string.ts' import { Override } from '../../../lib/util.ts' @@ -48,12 +49,14 @@ export function ResetPasswordConfirmForm({ }} invalid={invalid || !token || !password} > -

- - You will receive an email with a "reset code". Enter that code here - then enter your new password. - -

+ +

+ + You will receive an email with a "reset code". Enter that code here + then enter your new password. + +

+
Reset code}> -

- - Enter the email you used to create your account. We'll send you a - "reset code" so you can set a new password. - -

+ +

+ + Enter the email you used to create your account. We'll send you a + "reset code" so you can set a new password. + +

+
) diff --git a/packages/oauth/oauth-provider/src/assets/app/views/authorize/reset-password/reset-password-view.tsx b/packages/oauth/oauth-provider/src/assets/app/views/authorize/reset-password/reset-password-view.tsx index 300ae8f8615..acb707d8ad9 100644 --- a/packages/oauth/oauth-provider/src/assets/app/views/authorize/reset-password/reset-password-view.tsx +++ b/packages/oauth/oauth-provider/src/assets/app/views/authorize/reset-password/reset-password-view.tsx @@ -65,7 +65,7 @@ export function ResetPasswordView({ cancelLabel={Back} onCancel={onBack} /> -
+