Skip to content

Commit 2bc59dc

Browse files
committed
feat(auth): add authentication; improve readme
1 parent d15c6d7 commit 2bc59dc

27 files changed

Lines changed: 2225 additions & 401 deletions

playground/app.vue

Lines changed: 53 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,59 @@
1-
<template>
2-
<div>
3-
Nuxt EdgeDB playground!
1+
<script setup lang="ts">
2+
const { isLoggedIn } = useEdgeDbIdentity()
43
5-
<div>
6-
Blogposts:
7-
{{ data }}
8-
</div>
4+
const links = computed(() => {
5+
const links = [
6+
{
7+
label: 'Home',
8+
icon: 'i-heroicons-home',
9+
to: '/'
10+
},
11+
]
912
10-
<div>
11-
Add a new client:
12-
<input placeholder="thecompaniesapi.com">
13-
<button @click="submit">
14-
{{ loading ? 'Loading...' : 'Submit' }}
15-
</button>
16-
</div>
13+
if (isLoggedIn.value) {
14+
links.push(
15+
{
16+
label: 'New blogpost',
17+
icon: 'i-heroicons-newspaper-20-solid',
18+
to: '/new'
19+
},
20+
{
21+
label: 'Logout',
22+
icon: 'i-heroicons-newspaper-20-solid',
23+
to: '/auth/logout'
24+
}
25+
)
26+
} else {
27+
links.push(
28+
{
29+
label: 'Register',
30+
icon: 'i-heroicons-key-20-solid',
31+
to: '/auth/signup'
32+
},
33+
{
34+
label: 'Login',
35+
icon: 'i-heroicons-lock-open-20-solid',
36+
to: '/auth/login'
37+
},
38+
{
39+
label: 'Forgot my password',
40+
icon: 'i-heroicons-sparkles-20-solid',
41+
to: '/auth/forgot-password'
42+
},
43+
)
44+
}
1745
18-
<div v-if="error">
19-
{{ error }}
20-
</div>
21-
</div>
22-
</template>
46+
return links
47+
})
2348
24-
<script lang="ts" setup>
25-
const loading = ref(false);
26-
const error = ref("");
27-
const clientInput = ref();
49+
</script>
2850

29-
const { data, refresh } = await useAsyncData(
30-
'blogpost-index',
31-
() => $fetch('/api/blogpost')
32-
)
51+
<template>
52+
<UContainer class="p-8 flex flex-col gap-4">
53+
<UVerticalNavigation :links="links" />
3354

34-
const submit = async () => {
35-
loading.value = true
36-
error.value = ""
37-
try {
38-
await $fetch('/api/client/create', {
39-
query: {
40-
domain: clientInput.value
41-
}
42-
})
43-
await refresh()
44-
} catch (e: any) {
45-
console.log(e);
46-
error.value = e;
47-
}
48-
loading.value = false
49-
}
50-
</script>
55+
<div>
56+
<NuxtPage />
57+
</div>
58+
</UContainer>
59+
</template>

playground/assets/css/app.css

Whitespace-only changes.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<template>
2+
<EdgeDbAuthProviders v-slot="{ oAuthProviders: providers }">
3+
<EdgeDbOAuthButton
4+
v-for="provider of providers"
5+
:key="provider.name"
6+
v-slot="{ redirect }"
7+
:provider="provider.name"
8+
>
9+
<UButton @click="() => redirect()">
10+
{{ provider.display_name }}
11+
</UButton>
12+
</EdgeDbOAuthButton>
13+
</EdgeDbAuthProviders>
14+
</template>

playground/dbschema/default.esdl

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,40 @@
1+
using extension auth;
2+
13
module default {
4+
global current_user := (
5+
assert_single((
6+
select User { id, name }
7+
filter .identity = global ext::auth::ClientTokenIdentity
8+
))
9+
);
10+
11+
type User {
12+
required name: str;
13+
required identity: ext::auth::Identity;
14+
multi link posts -> BlogPost {
15+
on source delete delete target;
16+
}
17+
}
18+
219
type BlogPost {
3-
required property title -> str;
4-
property description -> str;
5-
required property content -> str {
6-
default := ""
20+
property content: str {
21+
default := 'My blog post content.';
22+
};
23+
property description: str {
24+
default := 'My blog post description.';
25+
};
26+
property title: str {
27+
default := 'My blog post';
28+
};
29+
required author: User {
30+
default := global current_user;
731
};
32+
33+
access policy author_has_full_access
34+
allow all
35+
using (.author ?= global current_user);
36+
37+
access policy others_read_only
38+
allow select;
839
}
940
}
Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,26 @@
1-
CREATE MIGRATION m1jbkm4y44e6nhehi3rzza5kfylv3ymj4iy6vx6fftwae3pj5523fq
1+
CREATE MIGRATION m1axchg2g3dqbqj3762e34ypgx6ndkiyr6fpl2niu2elb3d3kr5nfq
22
ONTO initial
33
{
4+
CREATE EXTENSION pgcrypto VERSION '1.3';
5+
CREATE EXTENSION auth VERSION '1.0';
6+
CREATE TYPE default::User {
7+
CREATE REQUIRED LINK identity: ext::auth::Identity;
8+
CREATE REQUIRED PROPERTY name: std::str;
9+
};
10+
CREATE GLOBAL default::current_user := (std::assert_single((SELECT
11+
default::User {
12+
id,
13+
name
14+
}
15+
FILTER
16+
(.identity = GLOBAL ext::auth::ClientTokenIdentity)
17+
)));
418
CREATE TYPE default::BlogPost {
5-
CREATE REQUIRED PROPERTY content: std::str {
6-
SET default := '';
7-
};
8-
CREATE REQUIRED PROPERTY title: std::str;
19+
CREATE REQUIRED LINK author: default::User;
20+
CREATE ACCESS POLICY author_has_full_access
21+
ALLOW ALL USING ((.author ?= GLOBAL default::current_user));
22+
CREATE ACCESS POLICY others_read_only
23+
ALLOW SELECT ;
24+
CREATE REQUIRED PROPERTY text: std::str;
925
};
1026
};
Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
1-
CREATE MIGRATION m1zwrwacfwgbpled2oup7peti2gy2szzsyrehrdtfd6pz6e77yxfrq
2-
ONTO m1jbkm4y44e6nhehi3rzza5kfylv3ymj4iy6vx6fftwae3pj5523fq
1+
CREATE MIGRATION m1lmflqgxsmihc4iyaiz37ujsrhjqznhkbxbljgpfk32424z6o54oq
2+
ONTO m1axchg2g3dqbqj3762e34ypgx6ndkiyr6fpl2niu2elb3d3kr5nfq
33
{
4-
DROP TYPE default::BlogPost;
4+
ALTER TYPE default::BlogPost {
5+
CREATE PROPERTY content: std::str {
6+
SET default := 'My blog post content.';
7+
};
8+
};
9+
ALTER TYPE default::BlogPost {
10+
CREATE PROPERTY description: std::str {
11+
SET default := 'My blog post description.';
12+
};
13+
};
14+
ALTER TYPE default::BlogPost {
15+
DROP PROPERTY text;
16+
};
17+
ALTER TYPE default::BlogPost {
18+
CREATE PROPERTY title: std::str {
19+
SET default := 'My blog post';
20+
};
21+
};
522
};
Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
CREATE MIGRATION m1eittjmr3ry4x23hx5bll3qlbj6a6trigilzj2mavjzid3xfuphka
2-
ONTO m1zwrwacfwgbpled2oup7peti2gy2szzsyrehrdtfd6pz6e77yxfrq
1+
CREATE MIGRATION m1x3k4pj7vpulmz2lt2xgos2rvqlpbo35iymu4prcgfsuvcixy6unq
2+
ONTO m1lmflqgxsmihc4iyaiz37ujsrhjqznhkbxbljgpfk32424z6o54oq
33
{
4-
CREATE TYPE default::BlogPost {
5-
CREATE REQUIRED PROPERTY content: std::str {
6-
SET default := '';
4+
ALTER TYPE default::BlogPost {
5+
ALTER LINK author {
6+
SET default := (GLOBAL default::current_user);
77
};
8-
CREATE REQUIRED PROPERTY title: std::str;
98
};
109
};
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
CREATE MIGRATION m1sud5ypmrvg5fcfusxf7miibzdzcv4d3jwsaowipxnkcor5v2f77q
2-
ONTO m1eittjmr3ry4x23hx5bll3qlbj6a6trigilzj2mavjzid3xfuphka
1+
CREATE MIGRATION m1o7wch7mvqsqf6du5jqax4udzgnda6w5qdftr527ev27whifzlzoa
2+
ONTO m1x3k4pj7vpulmz2lt2xgos2rvqlpbo35iymu4prcgfsuvcixy6unq
33
{
4-
ALTER TYPE default::BlogPost {
5-
CREATE PROPERTY description: std::str;
4+
ALTER TYPE default::User {
5+
CREATE MULTI LINK posts: default::BlogPost {
6+
ON SOURCE DELETE DELETE TARGET;
7+
};
68
};
79
};

playground/nuxt.config.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
export default defineNuxtConfig({
2-
modules: ['../src/module'],
3-
edgeDb: {},
2+
modules: [
3+
'../src/module',
4+
'@nuxt/ui'
5+
],
6+
edgeDb: {
7+
auth: true,
8+
oauth: true
9+
},
410
devtools: { enabled: true }
511
})

playground/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"nuxt": "latest"
1313
},
1414
"dependencies": {
15-
"@edgedb/generate": "^0.4.1"
15+
"@edgedb/generate": "^0.4.1",
16+
"@nuxt/ui": "^2.10.0"
1617
}
1718
}

0 commit comments

Comments
 (0)