Skip to content

Commit

Permalink
feat(auth): add authentication; improve readme
Browse files Browse the repository at this point in the history
  • Loading branch information
Tahul committed Nov 13, 2023
1 parent d15c6d7 commit 2bc59dc
Show file tree
Hide file tree
Showing 27 changed files with 2,225 additions and 401 deletions.
97 changes: 53 additions & 44 deletions playground/app.vue
Original file line number Diff line number Diff line change
@@ -1,50 +1,59 @@
<template>
<div>
Nuxt EdgeDB playground!
<script setup lang="ts">
const { isLoggedIn } = useEdgeDbIdentity()
<div>
Blogposts:
{{ data }}
</div>
const links = computed(() => {
const links = [
{
label: 'Home',
icon: 'i-heroicons-home',
to: '/'
},
]
<div>
Add a new client:
<input placeholder="thecompaniesapi.com">
<button @click="submit">
{{ loading ? 'Loading...' : 'Submit' }}
</button>
</div>
if (isLoggedIn.value) {
links.push(
{
label: 'New blogpost',
icon: 'i-heroicons-newspaper-20-solid',
to: '/new'
},
{
label: 'Logout',
icon: 'i-heroicons-newspaper-20-solid',
to: '/auth/logout'
}
)
} else {
links.push(
{
label: 'Register',
icon: 'i-heroicons-key-20-solid',
to: '/auth/signup'
},
{
label: 'Login',
icon: 'i-heroicons-lock-open-20-solid',
to: '/auth/login'
},
{
label: 'Forgot my password',
icon: 'i-heroicons-sparkles-20-solid',
to: '/auth/forgot-password'
},
)
}
<div v-if="error">
{{ error }}
</div>
</div>
</template>
return links
})
<script lang="ts" setup>
const loading = ref(false);
const error = ref("");
const clientInput = ref();
</script>

const { data, refresh } = await useAsyncData(
'blogpost-index',
() => $fetch('/api/blogpost')
)
<template>
<UContainer class="p-8 flex flex-col gap-4">
<UVerticalNavigation :links="links" />

const submit = async () => {
loading.value = true
error.value = ""
try {
await $fetch('/api/client/create', {
query: {
domain: clientInput.value
}
})
await refresh()
} catch (e: any) {
console.log(e);
error.value = e;
}
loading.value = false
}
</script>
<div>
<NuxtPage />
</div>
</UContainer>
</template>
Empty file added playground/assets/css/app.css
Empty file.
14 changes: 14 additions & 0 deletions playground/components/OAuthProviders.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<template>
<EdgeDbAuthProviders v-slot="{ oAuthProviders: providers }">
<EdgeDbOAuthButton
v-for="provider of providers"
:key="provider.name"
v-slot="{ redirect }"
:provider="provider.name"
>
<UButton @click="() => redirect()">
{{ provider.display_name }}
</UButton>
</EdgeDbOAuthButton>
</EdgeDbAuthProviders>
</template>
39 changes: 35 additions & 4 deletions playground/dbschema/default.esdl
Original file line number Diff line number Diff line change
@@ -1,9 +1,40 @@
using extension auth;

module default {
global current_user := (
assert_single((
select User { id, name }
filter .identity = global ext::auth::ClientTokenIdentity
))
);

type User {
required name: str;
required identity: ext::auth::Identity;
multi link posts -> BlogPost {
on source delete delete target;
}
}

type BlogPost {
required property title -> str;
property description -> str;
required property content -> str {
default := ""
property content: str {
default := 'My blog post content.';
};
property description: str {
default := 'My blog post description.';
};
property title: str {
default := 'My blog post';
};
required author: User {
default := global current_user;
};

access policy author_has_full_access
allow all
using (.author ?= global current_user);

access policy others_read_only
allow select;
}
}
26 changes: 21 additions & 5 deletions playground/dbschema/migrations/00001.edgeql
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
CREATE MIGRATION m1jbkm4y44e6nhehi3rzza5kfylv3ymj4iy6vx6fftwae3pj5523fq
CREATE MIGRATION m1axchg2g3dqbqj3762e34ypgx6ndkiyr6fpl2niu2elb3d3kr5nfq
ONTO initial
{
CREATE EXTENSION pgcrypto VERSION '1.3';
CREATE EXTENSION auth VERSION '1.0';
CREATE TYPE default::User {
CREATE REQUIRED LINK identity: ext::auth::Identity;
CREATE REQUIRED PROPERTY name: std::str;
};
CREATE GLOBAL default::current_user := (std::assert_single((SELECT
default::User {
id,
name
}
FILTER
(.identity = GLOBAL ext::auth::ClientTokenIdentity)
)));
CREATE TYPE default::BlogPost {
CREATE REQUIRED PROPERTY content: std::str {
SET default := '';
};
CREATE REQUIRED PROPERTY title: std::str;
CREATE REQUIRED LINK author: default::User;
CREATE ACCESS POLICY author_has_full_access
ALLOW ALL USING ((.author ?= GLOBAL default::current_user));
CREATE ACCESS POLICY others_read_only
ALLOW SELECT ;
CREATE REQUIRED PROPERTY text: std::str;
};
};
23 changes: 20 additions & 3 deletions playground/dbschema/migrations/00002.edgeql
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
CREATE MIGRATION m1zwrwacfwgbpled2oup7peti2gy2szzsyrehrdtfd6pz6e77yxfrq
ONTO m1jbkm4y44e6nhehi3rzza5kfylv3ymj4iy6vx6fftwae3pj5523fq
CREATE MIGRATION m1lmflqgxsmihc4iyaiz37ujsrhjqznhkbxbljgpfk32424z6o54oq
ONTO m1axchg2g3dqbqj3762e34ypgx6ndkiyr6fpl2niu2elb3d3kr5nfq
{
DROP TYPE default::BlogPost;
ALTER TYPE default::BlogPost {
CREATE PROPERTY content: std::str {
SET default := 'My blog post content.';
};
};
ALTER TYPE default::BlogPost {
CREATE PROPERTY description: std::str {
SET default := 'My blog post description.';
};
};
ALTER TYPE default::BlogPost {
DROP PROPERTY text;
};
ALTER TYPE default::BlogPost {
CREATE PROPERTY title: std::str {
SET default := 'My blog post';
};
};
};
11 changes: 5 additions & 6 deletions playground/dbschema/migrations/00003.edgeql
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
CREATE MIGRATION m1eittjmr3ry4x23hx5bll3qlbj6a6trigilzj2mavjzid3xfuphka
ONTO m1zwrwacfwgbpled2oup7peti2gy2szzsyrehrdtfd6pz6e77yxfrq
CREATE MIGRATION m1x3k4pj7vpulmz2lt2xgos2rvqlpbo35iymu4prcgfsuvcixy6unq
ONTO m1lmflqgxsmihc4iyaiz37ujsrhjqznhkbxbljgpfk32424z6o54oq
{
CREATE TYPE default::BlogPost {
CREATE REQUIRED PROPERTY content: std::str {
SET default := '';
ALTER TYPE default::BlogPost {
ALTER LINK author {
SET default := (GLOBAL default::current_user);
};
CREATE REQUIRED PROPERTY title: std::str;
};
};
10 changes: 6 additions & 4 deletions playground/dbschema/migrations/00004.edgeql
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
CREATE MIGRATION m1sud5ypmrvg5fcfusxf7miibzdzcv4d3jwsaowipxnkcor5v2f77q
ONTO m1eittjmr3ry4x23hx5bll3qlbj6a6trigilzj2mavjzid3xfuphka
CREATE MIGRATION m1o7wch7mvqsqf6du5jqax4udzgnda6w5qdftr527ev27whifzlzoa
ONTO m1x3k4pj7vpulmz2lt2xgos2rvqlpbo35iymu4prcgfsuvcixy6unq
{
ALTER TYPE default::BlogPost {
CREATE PROPERTY description: std::str;
ALTER TYPE default::User {
CREATE MULTI LINK posts: default::BlogPost {
ON SOURCE DELETE DELETE TARGET;
};
};
};
10 changes: 8 additions & 2 deletions playground/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
export default defineNuxtConfig({
modules: ['../src/module'],
edgeDb: {},
modules: [
'../src/module',
'@nuxt/ui'
],
edgeDb: {
auth: true,
oauth: true
},
devtools: { enabled: true }
})
3 changes: 2 additions & 1 deletion playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"nuxt": "latest"
},
"dependencies": {
"@edgedb/generate": "^0.4.1"
"@edgedb/generate": "^0.4.1",
"@nuxt/ui": "^2.10.0"
}
}
17 changes: 17 additions & 0 deletions playground/pages/auth/callback.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<template>
<div class="callback">
<EdgeDbOAuthCallback
v-slot="{ loading }"
redirect-to="/"
>
<UCard>
<template #header>
<h2>OAuth callback</h2>
</template>
<UButton :loading="loading">
Loading...
</UButton>
</UCard>
</EdgeDbOAuthCallback>
</div>
</template>
34 changes: 34 additions & 0 deletions playground/pages/auth/forgot-password.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<template>
<div class="login">
<EdgeDbAuthSendPasswordReset
v-slot="{ email, updateEmail, submit, loading }"
redirect-to="/"
>
<UCard>
<template #header>
<h2>Forgot my password</h2>
</template>
<div class="flex flex-col gap-4">
<UFormGroup label="Email">
<UInput
type="email"
:value="email"
placeholder="your@email.com"
@change="(e) => updateEmail(e.target.value)"
/>
</UFormGroup>
</div>

<template #footer>
<UButton
type="button"
:loading="loading"
@click="(e) => submit()"
>
Send reset email
</UButton>
</template>
</UCard>
</EdgeDbAuthSendPasswordReset>
</div>
</template>
52 changes: 52 additions & 0 deletions playground/pages/auth/login.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<template>
<div class="login">
<EdgeDbAuthEmailLogin
v-slot="{ email, updateEmail, password, updatePassword, submit, loading }"
redirect-to="/"
>
<UCard>
<template #header>
<h2>Login</h2>
</template>
<div class="flex flex-col gap-4">
<UFormGroup label="Email">
<UInput
type="email"
:value="email"
placeholder="your@email.com"
@change="(e) => updateEmail(e.target.value)"
/>
</UFormGroup>
<UFormGroup label="Password">
<UInput
type="password"
:value="password"
placeholder="password"
@change="(e) => updatePassword(e.target.value)"
/>
</UFormGroup>
</div>

<template #footer>
<div class="flex items-center gap-2">
<UButton
type="button"
:loading="loading"
@click="(e) => submit()"
>
Login
</UButton>

<OAuthProviders />
</div>
</template>
</UCard>
</EdgeDbAuthEmailLogin>
</div>
</template>

<style>
.blogpost-list {
}
</style>
13 changes: 13 additions & 0 deletions playground/pages/auth/logout.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<template>
<div class="login">
<EdgeDbAuthLogout
redirect-to="/"
>
<UCard>
<template #header>
<h2>Logout</h2>
</template>
</UCard>
</edgedbauthlogout>
</div>
</template>
Loading

0 comments on commit 2bc59dc

Please sign in to comment.