From 09c358522b443da253c001dcab747087a6ced1d8 Mon Sep 17 00:00:00 2001 From: Bernd Storath Date: Wed, 27 May 2026 15:54:10 +0200 Subject: [PATCH] link/unlink logic --- .../config/external-authentication.md | 33 +++++-- .../components/Base/FormSecondaryButton.vue | 26 +++++ .../components/Form/SecondaryActionField.vue | 5 +- src/app/components/Header/LangSelector.vue | 6 +- src/app/components/Icons/Brands/Provider.vue | 10 ++ src/app/components/Ui/LoginOauthButton.vue | 21 ++++ src/app/pages/login.vue | 53 ++-------- src/app/pages/me.vue | 98 +++++++++++++++++-- src/app/stores/auth.ts | 1 - src/app/utils/types.ts | 2 + src/i18n/locales/en.json | 11 ++- .../api/auth/[provider]/callback.get.ts | 41 ++------ src/server/api/auth/[provider]/index.get.ts | 17 +++- src/server/api/auth/[provider]/link.get.ts | 43 ++++++++ src/server/api/auth/methods.get.ts | 4 +- src/server/api/auth/unlink.post.ts | 11 +++ src/server/api/session.get.ts | 3 +- .../database/repositories/user/service.ts | 59 +++++++++++ src/server/utils/oauth.ts | 54 +++++++++- src/shared/utils/permissions.ts | 2 +- 20 files changed, 391 insertions(+), 109 deletions(-) create mode 100644 src/app/components/Base/FormSecondaryButton.vue create mode 100644 src/app/components/Icons/Brands/Provider.vue create mode 100644 src/app/components/Ui/LoginOauthButton.vue create mode 100644 src/server/api/auth/[provider]/link.get.ts create mode 100644 src/server/api/auth/unlink.post.ts diff --git a/docs/content/advanced/config/external-authentication.md b/docs/content/advanced/config/external-authentication.md index fb1a9393..5b74bcf7 100644 --- a/docs/content/advanced/config/external-authentication.md +++ b/docs/content/advanced/config/external-authentication.md @@ -18,21 +18,34 @@ You can enable multiple providers by separating them with a comma: e.g. `google,github` +### Redirect URIs + +You have to configure the following redirect URIs in your OAuth provider: + +- `https:///api/auth//callback` + Used to log in to with the provider +- `https:///api/auth//link` + Used to link an existing account to the provider + +If your provider does not support multiple redirect URIs (e.g. GitHub) but allows multiple URIs under the same base, then configure: + +- `https:///api/auth//` + ### Google -| Env | Required | Example | Description | -| ----------------------------- | -------- | -------------------------------- | ----------------------------------------- | -| `OAUTH_GOOGLE_CLIENT_ID` | ✔️ | `123.apps.googleusercontent.com` | Google Client ID | -| `OAUTH_GOOGLE_CLIENT_SECRET` | ✔️ | `GOCSPX-xxx` | Google Client Secret | -| `OAUTH_GOOGLE_ALLOWED_DOMAIN` | ✖️ | `example.com` | Restrict login to a specific email domain | +| Env | Required | Example | Description | +| ----------------------------- | -------- | ------------- | ----------------------------------------- | +| `OAUTH_GOOGLE_CLIENT_ID` | ✔️ | - | Google Client ID | +| `OAUTH_GOOGLE_CLIENT_SECRET` | ✔️ | - | Google Client Secret | +| `OAUTH_GOOGLE_ALLOWED_DOMAIN` | ✖️ | `example.com` | Restrict login to a specific email domain | #### Setup 1. Go to [Google Cloud Console](https://console.cloud.google.com/apis/credentials) 2. Create an OAuth 2.0 Client ID (Web application) -3. Add Authorized redirect URI: `https:///api/auth/google/callback` +3. Add Authorized redirect URI: See [Redirect URIs](#redirect-uris) 4. Copy the Client ID and Client Secret to the environment variables ### GitHub @@ -52,14 +65,15 @@ The provider needs to support: - PKCE - default scopes: `openid email profile` -- Valid HTTPS - Client Secret Authentication `client_secret_post` +The provider needs to be available with HTTPS and have a valid certificate. + | Env | Required | Default | Example | Description | | -------------------------- | -------- | ------- | -------------------------- | ------------------ | | `OAUTH_OIDC_SERVER` | ✔️ | - | `https://auth.example.com` | OIDC Server | -| `OAUTH_OIDC_CLIENT_ID` | ✔️ | - | `xxx` | OIDC Client ID | -| `OAUTH_OIDC_CLIENT_SECRET` | ✔️ | - | `xxx` | OIDC Client Secret | +| `OAUTH_OIDC_CLIENT_ID` | ✔️ | - | - | OIDC Client ID | +| `OAUTH_OIDC_CLIENT_SECRET` | ✔️ | - | - | OIDC Client Secret | | `OAUTH_OIDC_NAME` | ✖️ | OIDC | `Authelia` | Provider Name | #### Authelia Setup @@ -79,6 +93,7 @@ docker run --rm authelia/authelia:latest authelia crypto hash generate pbkdf2 -- client_secret: '$pbkdf2-...' redirect_uris: - https:///api/auth/oidc/callback + - https:///api/auth/oidc/link scopes: - openid - profile diff --git a/src/app/components/Base/FormSecondaryButton.vue b/src/app/components/Base/FormSecondaryButton.vue new file mode 100644 index 00000000..d9c6c71a --- /dev/null +++ b/src/app/components/Base/FormSecondaryButton.vue @@ -0,0 +1,26 @@ + + + diff --git a/src/app/components/Form/SecondaryActionField.vue b/src/app/components/Form/SecondaryActionField.vue index 7d8cefaf..94878c55 100644 --- a/src/app/components/Form/SecondaryActionField.vue +++ b/src/app/components/Form/SecondaryActionField.vue @@ -1,8 +1,9 @@ diff --git a/src/app/components/Header/LangSelector.vue b/src/app/components/Header/LangSelector.vue index c0452def..1d302e9e 100644 --- a/src/app/components/Header/LangSelector.vue +++ b/src/app/components/Header/LangSelector.vue @@ -1,12 +1,14 @@