Skip to content

Commit 8fdaaf2

Browse files
committed
Add a generic OIDC OAuth2 provider
1 parent 9174d8f commit 8fdaaf2

File tree

7 files changed

+154
-3
lines changed

7 files changed

+154
-3
lines changed

CONTRIBUTING.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,15 @@ git clone https://github.com/appwrite/console.git appwrite-console
4040
```
4141

4242
### 2. Install dependencies with npm
43+
4344
Navigate to the Appwrite Console repository and install dependencies.
45+
4446
```bash
4547
cd appwrite-console && npm install
4648
```
4749

4850
### 3. Install and run Appwrite locally
51+
4952
When you run the Appwrite Console locally, it needs to point to a backend as well. The easiest way to do this is to run an Appwrite instance locally.
5053

5154
Follow the [install instructions](https://appwrite.io/docs/installation) in the Appwrite docs.

src/lib/stores/oauth-providers.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
import { writable } from 'svelte/store';
21
import type { Models } from '@appwrite.io/console';
32
import type { SvelteComponent } from 'svelte';
3+
import { writable } from 'svelte/store';
44
import Apple from '../../routes/console/project-[project]/auth/appleOAuth.svelte';
5-
import Microsoft from '../../routes/console/project-[project]/auth/microsoftOAuth.svelte';
6-
import Okta from '../../routes/console/project-[project]/auth/oktaOAuth.svelte';
75
import Auth0 from '../../routes/console/project-[project]/auth/auth0OAuth.svelte';
86
import Authentik from '../../routes/console/project-[project]/auth/authentikOAuth.svelte';
97
import GitLab from '../../routes/console/project-[project]/auth/gitlabOAuth.svelte';
108
import Main from '../../routes/console/project-[project]/auth/mainOAuth.svelte';
9+
import Microsoft from '../../routes/console/project-[project]/auth/microsoftOAuth.svelte';
10+
import Oidc from '../../routes/console/project-[project]/auth/oidcOAuth.svelte';
11+
import Okta from '../../routes/console/project-[project]/auth/oktaOAuth.svelte';
1112

1213
export type Provider = Models.Provider & {
1314
icon: string;
@@ -92,6 +93,10 @@ const setProviders = (project: Models.Project): Provider[] => {
9293
case 'notion':
9394
docs = 'https://developers.notion.com/docs';
9495
break;
96+
case 'oidc':
97+
docs = 'https://openid.net/connect/faq/';
98+
component = Oidc;
99+
break;
95100
case 'okta':
96101
docs = 'https://developer.okta.com';
97102
component = Okta;
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<script lang="ts">
2+
import { page } from '$app/stores';
3+
import { Alert, CopyInput, Modal } from '$lib/components';
4+
import { Button, FormList, InputPassword, InputSwitch, InputText } from '$lib/elements/forms';
5+
import type { Provider } from '$lib/stores/oauth-providers';
6+
import { sdk } from '$lib/stores/sdk';
7+
import { onMount } from 'svelte';
8+
import { updateOAuth } from './updateOAuth';
9+
10+
const projectId = $page.params.project;
11+
12+
export let provider: Provider;
13+
14+
let appId: string = null;
15+
let enabled: boolean = null;
16+
let clientSecret: string = null;
17+
let wellKnownEndpoint: string = null;
18+
let authorizationEndpoint: string = null;
19+
let tokenEndpoint: string = null;
20+
let userinfoEndpoint: string = null;
21+
let error: string;
22+
23+
// secret is valid if clientSecret is set and either wellKnownEndpoint or all of the other endpoints are set
24+
$: isValidSecret =
25+
clientSecret &&
26+
(wellKnownEndpoint || (authorizationEndpoint && tokenEndpoint && userinfoEndpoint));
27+
28+
onMount(() => {
29+
appId ??= provider.appId;
30+
enabled ??= provider.enabled;
31+
if (provider.secret) {
32+
({
33+
clientSecret,
34+
wellKnownEndpoint,
35+
authorizationEndpoint,
36+
tokenEndpoint,
37+
userinfoEndpoint
38+
} = JSON.parse(provider.secret));
39+
}
40+
});
41+
42+
const update = async () => {
43+
const result = await updateOAuth({ projectId, provider, secret, appId, enabled });
44+
45+
if (result.status === 'error') {
46+
error = result.message;
47+
} else {
48+
provider = null;
49+
}
50+
};
51+
52+
$: secret = isValidSecret
53+
? JSON.stringify({
54+
clientSecret,
55+
wellKnownEndpoint,
56+
authorizationEndpoint,
57+
tokenEndpoint,
58+
userinfoEndpoint
59+
})
60+
: provider.secret;
61+
</script>
62+
63+
<Modal {error} onSubmit={update} size="big" show on:close>
64+
<svelte:fragment slot="header">{provider.name.toUpperCase()} OAuth2 Settings</svelte:fragment>
65+
<FormList>
66+
<p>
67+
To use {provider.name.toUpperCase()} authentication in your application, first fill in this
68+
form. For more info you can
69+
<a class="link" href={provider.docs} target="_blank" rel="noopener noreferrer"
70+
>visit the docs.</a>
71+
</p>
72+
<InputSwitch id="state" bind:value={enabled} label={enabled ? 'Enabled' : 'Disabled'} />
73+
<InputText
74+
id="appID"
75+
label="Client ID"
76+
autofocus={true}
77+
placeholder="Enter ID"
78+
bind:value={appId} />
79+
<InputPassword
80+
id="secret"
81+
label="Client Secret"
82+
placeholder="Enter Client Secret"
83+
minlength={0}
84+
showPasswordButton
85+
bind:value={clientSecret} />
86+
<InputText
87+
id="well-known-endpoint"
88+
label="Well-Known Endpoint"
89+
placeholder="https://example.com/.well-known/openid-configuration"
90+
bind:value={wellKnownEndpoint} />
91+
<InputText
92+
id="authorization-endpoint"
93+
label="Authorization Endpoint"
94+
placeholder="https://example.com/authorize"
95+
bind:value={authorizationEndpoint} />
96+
<InputText
97+
id="token-endpoint"
98+
label="Token Endpoint"
99+
placeholder="https://example.com/token"
100+
bind:value={tokenEndpoint} />
101+
<InputText
102+
id="userinfo-endpoint"
103+
label="User Info Endpoint"
104+
placeholder="https://example.com/userinfo"
105+
bind:value={userinfoEndpoint} />
106+
107+
<Alert type="info">
108+
To complete set up, add this OAuth2 redirect URI to your {provider.name} app configuration.
109+
</Alert>
110+
<div>
111+
<p>URI</p>
112+
<CopyInput
113+
value={`${
114+
sdk.forConsole.client.config.endpoint
115+
}/account/sessions/oauth2/callback/${provider.name.toLocaleLowerCase()}/${projectId}`} />
116+
</div>
117+
</FormList>
118+
<svelte:fragment slot="footer">
119+
<Button secondary on:click={() => (provider = null)}>Cancel</Button>
120+
<Button
121+
disabled={(secret === provider.secret &&
122+
enabled === provider.enabled &&
123+
appId === provider.appId) ||
124+
!(appId && isValidSecret)}
125+
submit>Update</Button>
126+
</svelte:fragment>
127+
</Modal>

static/icons/dark/color/oidc.svg

Lines changed: 4 additions & 0 deletions
Loading
Lines changed: 4 additions & 0 deletions
Loading

static/icons/light/color/oidc.svg

Lines changed: 4 additions & 0 deletions
Loading
Lines changed: 4 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)