From 09e0a086caa51c7d4971d07509863a45a9babb43 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Thu, 5 Oct 2023 22:28:56 +0100 Subject: [PATCH 1/2] Add `additional_scope` to providers + `redirect_to_on_signup` to ui config --- shared/studio/tabs/auth/authAdmin.module.scss | 7 +++ shared/studio/tabs/auth/index.tsx | 44 ++++++++++++++++++- shared/studio/tabs/auth/state/index.tsx | 25 ++++++++++- 3 files changed, 73 insertions(+), 3 deletions(-) diff --git a/shared/studio/tabs/auth/authAdmin.module.scss b/shared/studio/tabs/auth/authAdmin.module.scss index c4e5ca6b..3faf3ab4 100644 --- a/shared/studio/tabs/auth/authAdmin.module.scss +++ b/shared/studio/tabs/auth/authAdmin.module.scss @@ -368,6 +368,13 @@ @include hideScrollbar; } + .providerConfigValue { + span { + opacity: 0.7; + font-style: italic; + } + } + @include darkTheme { background-color: #2f2f2f; diff --git a/shared/studio/tabs/auth/index.tsx b/shared/studio/tabs/auth/index.tsx index f23a2faa..0014b6fc 100644 --- a/shared/studio/tabs/auth/index.tsx +++ b/shared/studio/tabs/auth/index.tsx @@ -268,7 +268,26 @@ const UIConfigForm = observer(function UIConfig({ />
- The url to redirect to after successful login. + The url to redirect to after successful sign in. +
+ + + +
+
redirect_to_on_signup
+
+
+ + draft.setConfigValue("redirect_to_on_signup", val) + } + /> +
+
+ The url to redirect to after a new user signs up. If not set, + 'redirect_to' will be used instead.
@@ -573,6 +592,22 @@ const DraftProviderConfigForm = observer(function DraftProviderConfigForm({ +
+
additional_scope
+
+
+ draftState.setAdditionalScope(val)} + /> +
+
+ Space-separated list of scopes to be included in the + authorize request to the OAuth provider. +
+
+
) : null} @@ -645,6 +680,13 @@ function ProviderCard({provider}: {provider: AuthProviderData}) {
secret
{secretPlaceholder}
+ +
additional_scope
+
+ {(provider as OAuthProviderData).additional_scope || ( + none + )} +
) : null} diff --git a/shared/studio/tabs/auth/state/index.tsx b/shared/studio/tabs/auth/state/index.tsx index 8ef8479e..2ca8c6ea 100644 --- a/shared/studio/tabs/auth/state/index.tsx +++ b/shared/studio/tabs/auth/state/index.tsx @@ -25,6 +25,7 @@ export type OAuthProviderData = { | "ext::auth::GitHubOAuthProvider" | "ext::auth::GoogleOAuthProvider"; client_id: string; + additional_scope: string; }; export type AuthProviderData = | OAuthProviderData @@ -32,6 +33,7 @@ export type AuthProviderData = export interface AuthUIConfigData { redirect_to: string; + redirect_to_on_signup: string; app_name: string | null; logo_url: string | null; dark_logo_url: string | null; @@ -187,9 +189,11 @@ export class AuthAdminState extends Model({ _typename := .__type__.name, name, [is OAuthProviderConfig].client_id, + [is OAuthProviderConfig].additional_scope, }, ui: { redirect_to, + redirect_to_on_signup, app_name, logo_url, dark_logo_url, @@ -221,6 +225,7 @@ export class AuthAdminState extends Model({ @model("AdminDraftUIConfig") export class DraftUIConfig extends Model({ _redirect_to: prop(null), + _redirect_to_on_signup: prop(null), _app_name: prop(null), _logo_url: prop(null), _dark_logo_url: prop(null), @@ -257,6 +262,7 @@ export class DraftUIConfig extends Model({ get formChanged() { return ( this._redirect_to != null || + this._redirect_to_on_signup != null || this._app_name != null || this._logo_url != null || this._dark_logo_url != null || @@ -267,6 +273,7 @@ export class DraftUIConfig extends Model({ @modelAction clearForm() { this._redirect_to = null; + this._redirect_to_on_signup = null; this._app_name = null; this._logo_url = null; this._dark_logo_url = null; @@ -298,7 +305,13 @@ export class DraftUIConfig extends Model({ this.getConfigValue("redirect_to") )}, ${( - ["app_name", "logo_url", "dark_logo_url", "brand_color"] as const + [ + "redirect_to_on_signup", + "app_name", + "logo_url", + "dark_logo_url", + "brand_color", + ] as const ) .map((name) => { const val = this.getConfigValue(name); @@ -325,6 +338,7 @@ export class DraftProviderConfig extends Model({ oauthClientId: prop("").withSetter(), oauthSecret: prop("").withSetter(), + additionalScope: prop("").withSetter(), }) { @computed get oauthClientIdError() { @@ -372,7 +386,14 @@ export class DraftProviderConfig extends Model({ provider.kind === "OAuth" ? ` client_id := ${JSON.stringify(this.oauthClientId)}, - secret := ${JSON.stringify(this.oauthSecret)} + secret := ${JSON.stringify(this.oauthSecret)}, + ${ + this.additionalScope.trim() + ? `additional_scope := ${JSON.stringify( + this.additionalScope.trim() + )}` + : "" + } ` : "" } From 5bbec44587f7360945ff07907df1e762e512539d Mon Sep 17 00:00:00 2001 From: James Clarke Date: Fri, 20 Oct 2023 22:25:26 +0100 Subject: [PATCH 2/2] Add `require_verification` config --- shared/studio/tabs/auth/authAdmin.module.scss | 26 +++++++ shared/studio/tabs/auth/index.tsx | 67 +++++++++++++++---- shared/studio/tabs/auth/state/index.tsx | 14 +++- 3 files changed, 92 insertions(+), 15 deletions(-) diff --git a/shared/studio/tabs/auth/authAdmin.module.scss b/shared/studio/tabs/auth/authAdmin.module.scss index 3faf3ab4..e00e2aed 100644 --- a/shared/studio/tabs/auth/authAdmin.module.scss +++ b/shared/studio/tabs/auth/authAdmin.module.scss @@ -258,6 +258,32 @@ } } +.checkbox { + display: flex; + padding: 7px; + margin: 0 -7px; + cursor: pointer; + + input { + appearance: none; + width: 20px; + height: 20px; + margin: 0; + outline: 0; + border: 2px solid #9a9a9a; + border-radius: 4px; + background: transparent no-repeat center center; + box-sizing: border-box; + cursor: pointer; + + &:checked { + background-color: #1f8aed; + border: none; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14'%3E%3Cpath fill='%23fff' d='M0,8 5,13 14,4 12,2 5,9 2,6z'/%3E%3C/svg%3E"); + } + } +} + .providersList { display: flex; flex-direction: column; diff --git a/shared/studio/tabs/auth/index.tsx b/shared/studio/tabs/auth/index.tsx index 0014b6fc..bf19fdea 100644 --- a/shared/studio/tabs/auth/index.tsx +++ b/shared/studio/tabs/auth/index.tsx @@ -19,6 +19,7 @@ import { DraftUIConfig, ProviderKind, OAuthProviderData, + LocalEmailPasswordProviderData, } from "./state"; import {useTabState} from "../../state"; import {encodeB64} from "edgedb/dist/primitives/buffer"; @@ -609,6 +610,27 @@ const DraftProviderConfigForm = observer(function DraftProviderConfigForm({ + ) : providerKind === "Local" ? ( +
+
require_verification
+
+
+ +
+
+ Whether the email needs to be verified before the user is + allowed to sign in. +
+
+
) : null} @@ -647,7 +669,7 @@ function ProviderCard({provider}: {provider: AuthProviderData}) {
setExpanded(!expanded)} > @@ -671,22 +693,39 @@ function ProviderCard({provider}: {provider: AuthProviderData}) { }} />
- {expanded && kind === "OAuth" ? ( + {expanded ? (
-
client_id
-
- {(provider as OAuthProviderData).client_id} -
+ {kind === "OAuth" ? ( + <> +
client_id
+
+ {(provider as OAuthProviderData).client_id} +
-
secret
-
{secretPlaceholder}
+
secret
+
+ {secretPlaceholder} +
-
additional_scope
-
- {(provider as OAuthProviderData).additional_scope || ( - none - )} -
+
additional_scope
+
+ {(provider as OAuthProviderData).additional_scope || ( + none + )} +
+ + ) : kind === "Local" ? ( + <> +
+ require_verification +
+
+ {( + provider as LocalEmailPasswordProviderData + ).require_verification.toString()} +
+ + ) : null}
) : null} diff --git a/shared/studio/tabs/auth/state/index.tsx b/shared/studio/tabs/auth/state/index.tsx index 2ca8c6ea..eb30e375 100644 --- a/shared/studio/tabs/auth/state/index.tsx +++ b/shared/studio/tabs/auth/state/index.tsx @@ -27,9 +27,14 @@ export type OAuthProviderData = { client_id: string; additional_scope: string; }; +export type LocalEmailPasswordProviderData = { + name: string; + _typename: "ext::auth::EmailPasswordProviderConfig"; + require_verification: boolean; +}; export type AuthProviderData = | OAuthProviderData - | {name: string; _typename: "ext::auth::EmailPasswordProviderConfig"}; + | LocalEmailPasswordProviderData; export interface AuthUIConfigData { redirect_to: string; @@ -190,6 +195,7 @@ export class AuthAdminState extends Model({ name, [is OAuthProviderConfig].client_id, [is OAuthProviderConfig].additional_scope, + [is EmailPasswordProviderConfig].require_verification, }, ui: { redirect_to, @@ -339,6 +345,8 @@ export class DraftProviderConfig extends Model({ oauthClientId: prop("").withSetter(), oauthSecret: prop("").withSetter(), additionalScope: prop("").withSetter(), + + requireEmailVerification: prop(true).withSetter(), }) { @computed get oauthClientIdError() { @@ -395,6 +403,10 @@ export class DraftProviderConfig extends Model({ : "" } ` + : provider.kind === "Local" + ? `require_verification := ${ + this.requireEmailVerification ? "true" : "false" + },` : "" } }`