Skip to content

Commit

Permalink
use jwt for remote replication auth
Browse files Browse the repository at this point in the history
  • Loading branch information
talentedunicorn committed Dec 28, 2024
1 parent c6ce4ef commit 5f94ba7
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 124 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,5 @@ You can preview the production build with `pnpm run preview`.
- `VITE_GA_TAG` for Google Analytics tag
- `VITE_DB_NAME` the pouchdb database name
- `VITE_REMOTE_DB` remote pouchdb/couchdb database url. Required `VITE_SYNCED` to be `true`
- `VITE_REMOTE_DB_USERNAME` remote pouchdb/couchdb database username. Required `VITE_SYNCED` to be `true`
- `VITE_REMOTE_DB_PASSWORD` remote pouchdb/couchdb database password. Required `VITE_SYNCED` to be `true`
- `VITE_AUTH0_CLIENT` [Auth0](https://auth0.com/) client id
- `VITE_AUTH0_DOMAIN` [Auth0](https://auth0.com/) domain
2 changes: 0 additions & 2 deletions env.sample
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
VITE_DB_NAME=database_name
VITE_REMOTE_DB=remote_database_url
VITE_REMOTE_DB_USERNAME=database_username
VITE_REMOTE_DB_PASSWORD=database_password
VITE_GA_TAG=google_analytics_tag
VITE_SYNCED=true_or_false_to_toggle_remote_sync
VITE_AUTH0_DOMAIN=auth0_domain
Expand Down
87 changes: 17 additions & 70 deletions src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
import { pwaInfo } from 'virtual:pwa-info';
import ExportImport from './components/ExportImport.svelte';
import Toast from './components/Toast.svelte';
import ToggleTheme from './components/ToggleTheme.svelte';
import { toastActions, toastMessage } from './stores';
let auth0: Auth0Client;
let wrapper: HTMLElement;
let theme = $state<string | null>(null);
let menuItems = $derived(
tabs.map((item) => ({
Expand Down Expand Up @@ -46,26 +46,6 @@
});
};
const toggleTheme = () => {
const html = document.querySelector('html');
const themeData = html?.getAttribute('data-theme');
// const prefersDarkTheme = window.matchMedia('(prefers-color-scheme: dark)');
let nextTheme;
switch (themeData) {
case 'dark':
nextTheme = 'light';
break;
case 'light':
nextTheme = null;
break;
default:
nextTheme = 'dark';
break;
}
theme = nextTheme;
nextTheme ? html?.setAttribute('data-theme', nextTheme) : html?.removeAttribute('data-theme');
};
onMount(async () => {
handleBackToTop();
if (import.meta.env.VITE_SYNCED === 'true' && navigator.onLine) {
Expand Down Expand Up @@ -93,6 +73,7 @@
{#if import.meta.env.VITE_SYNCED === 'true' && !$isLoggedin}
<div class="Login">
<Logo />
<ToggleTheme />
<Button onclick={() => login(auth0)}>Log in</Button>
</div>
{:else}
Expand All @@ -103,11 +84,13 @@
</aside>
<header class="Header">
<h1 data-syncing={$status} class="Logo" title="ToDone"><Logo /></h1>

<ToggleTheme />
</header>
<section class="Content">
{#if $isLoggedin}
<div class="Profile">
{$user.name}
<img src={$user.picture} alt={$user.nickname} />
<Button onclick={() => logout(auth0)}>Log out</Button>
</div>
{/if}
Expand All @@ -126,48 +109,7 @@
>
</footer>
{/if}
<Button size="small" class="ColorToggle" variant="link" onclick={toggleTheme}>
{#if theme === 'dark'}
<svg
width="18"
height="18"
viewBox="0 0 24 24"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<title>Dark</title>
<path
d="M21.996 12.882c0.022-0.233-0.038-0.476-0.188-0.681-0.325-0.446-0.951-0.544-1.397-0.219-0.95 0.693-2.060 1.086-3.188 1.162-1.368 0.092-2.765-0.283-3.95-1.158-1.333-0.985-2.139-2.415-2.367-3.935s0.124-3.124 1.109-4.456c0.142-0.191 0.216-0.435 0.191-0.691-0.053-0.55-0.542-0.952-1.092-0.898-2.258 0.22-4.314 1.18-5.895 2.651-1.736 1.615-2.902 3.847-3.137 6.386-0.254 2.749 0.631 5.343 2.266 7.311s4.022 3.313 6.772 3.567 5.343-0.631 7.311-2.266 3.313-4.022 3.567-6.772zM19.567 14.674c-0.49 1.363-1.335 2.543-2.416 3.441-1.576 1.309-3.648 2.016-5.848 1.813s-4.108-1.278-5.417-2.854-2.016-3.648-1.813-5.848c0.187-2.032 1.117-3.814 2.507-5.106 0.782-0.728 1.71-1.3 2.731-1.672-0.456 1.264-0.577 2.606-0.384 3.899 0.303 2.023 1.38 3.934 3.156 5.247 1.578 1.167 3.448 1.668 5.272 1.545 0.752-0.050 1.496-0.207 2.21-0.465z"
></path>
</svg>
{:else if theme === 'light'}
<svg
width="18"
height="18"
viewBox="0 0 24 24"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<title>Light</title>
<path
d="M18 12c0-1.657-0.673-3.158-1.757-4.243s-2.586-1.757-4.243-1.757-3.158 0.673-4.243 1.757-1.757 2.586-1.757 4.243 0.673 3.158 1.757 4.243 2.586 1.757 4.243 1.757 3.158-0.673 4.243-1.757 1.757-2.586 1.757-4.243zM16 12c0 1.105-0.447 2.103-1.172 2.828s-1.723 1.172-2.828 1.172-2.103-0.447-2.828-1.172-1.172-1.723-1.172-2.828 0.447-2.103 1.172-2.828 1.723-1.172 2.828-1.172 2.103 0.447 2.828 1.172 1.172 1.723 1.172 2.828zM11 1v2c0 0.552 0.448 1 1 1s1-0.448 1-1v-2c0-0.552-0.448-1-1-1s-1 0.448-1 1zM11 21v2c0 0.552 0.448 1 1 1s1-0.448 1-1v-2c0-0.552-0.448-1-1-1s-1 0.448-1 1zM3.513 4.927l1.42 1.42c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414l-1.42-1.42c-0.391-0.391-1.024-0.391-1.414 0s-0.391 1.024 0 1.414zM17.653 19.067l1.42 1.42c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414l-1.42-1.42c-0.391-0.391-1.024-0.391-1.414 0s-0.391 1.024 0 1.414zM1 13h2c0.552 0 1-0.448 1-1s-0.448-1-1-1h-2c-0.552 0-1 0.448-1 1s0.448 1 1 1zM21 13h2c0.552 0 1-0.448 1-1s-0.448-1-1-1h-2c-0.552 0-1 0.448-1 1s0.448 1 1 1zM4.927 20.487l1.42-1.42c0.391-0.391 0.391-1.024 0-1.414s-1.024-0.391-1.414 0l-1.42 1.42c-0.391 0.391-0.391 1.024 0 1.414s1.024 0.391 1.414 0zM19.067 6.347l1.42-1.42c0.391-0.391 0.391-1.024 0-1.414s-1.024-0.391-1.414 0l-1.42 1.42c-0.391 0.391-0.391 1.024 0 1.414s1.024 0.391 1.414 0z"
></path>
</svg>
{:else}
<svg
width="18"
height="18"
viewBox="0 0 24 24"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<title>System</title>
<path
d="M6 5h12c0.276 0 0.525 0.111 0.707 0.293s0.293 0.431 0.293 0.707v12c0 0.276-0.111 0.525-0.293 0.707s-0.431 0.293-0.707 0.293h-12c-0.276 0-0.525-0.111-0.707-0.293s-0.293-0.431-0.293-0.707v-12c0-0.276 0.111-0.525 0.293-0.707s0.431-0.293 0.707-0.293zM9 8c-0.552 0-1 0.448-1 1v6c0 0.552 0.448 1 1 1h6c0.552 0 1-0.448 1-1v-6c0-0.552-0.448-1-1-1zM10 10h4v4h-4zM1 15h2v3c0 0.828 0.337 1.58 0.879 2.121s1.293 0.879 2.121 0.879h2v2c0 0.552 0.448 1 1 1s1-0.448 1-1v-2h4v2c0 0.552 0.448 1 1 1s1-0.448 1-1v-2h2c0.828 0 1.58-0.337 2.121-0.879s0.879-1.293 0.879-2.121v-3h2c0.552 0 1-0.448 1-1s-0.448-1-1-1h-2v-3h2c0.552 0 1-0.448 1-1s-0.448-1-1-1h-2v-2c0-0.828-0.337-1.58-0.879-2.121s-1.293-0.879-2.121-0.879h-2v-2c0-0.552-0.448-1-1-1s-1 0.448-1 1v2h-4v-2c0-0.552-0.448-1-1-1s-1 0.448-1 1v2h-2c-0.828 0-1.58 0.337-2.121 0.879s-0.879 1.293-0.879 2.121v2h-2c-0.552 0-1 0.448-1 1s0.448 1 1 1h2v3h-2c-0.552 0-1 0.448-1 1s0.448 1 1 1z"
></path>
</svg>
{/if}
</Button>

<Toast
message={$toastMessage}
close={() => {
Expand Down Expand Up @@ -197,16 +139,14 @@
min-height: 100vh;
}
:global(.ColorToggle) {
margin: auto auto 2rem 1rem;
position: sticky;
bottom: 2rem;
}
.Login {
padding: 2rem;
gap: 2rem;
align-items: flex-start;
:global(.ColorToggle) {
margin-left: auto;
}
}
.Menu {
Expand All @@ -217,6 +157,8 @@
.Header {
align-self: flex-end;
display: flex;
flex-direction: row-reverse;
}
.Logo {
Expand All @@ -241,6 +183,11 @@
margin: 2rem;
justify-content: end;
align-items: center;
img {
inline-size: 3rem;
border-radius: 100%;
}
}
[data-syncing] {
Expand Down
22 changes: 17 additions & 5 deletions src/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ export const checkAuth = async (auth0: Auth0Client) => {
// if code then login success
if (params.has('code')) {
// Let the Auth0 SDK do it's stuff - save some state, etc.
await auth0?.handleRedirectCallback();
await auth0.handleRedirectCallback();
// Can be smart here and redirect to original path instead of root
window.history.replaceState({}, document.title, '/');
}

const _isAuthenticated = await auth0?.isAuthenticated();
const _isAuthenticated = await auth0.isAuthenticated();
isLoggedin.set(_isAuthenticated);

if (_isAuthenticated) {
Expand All @@ -39,13 +39,25 @@ export const checkAuth = async (auth0: Auth0Client) => {

// Get the access token. Make sure to supply audience property
// in Auth0 config, otherwise you will soon start throwing stuff!
const _token = await auth0.getTokenSilently();
token.set(_token);
const { id_token } = await auth0.getTokenSilently({
authorizationParams: {
redirect_uri: window.location.origin
},
detailedResponse: true
});

token.set(id_token);

// refresh token after specific period or things will stop
// working. Useful for long-lived apps like dashboards.
intervalId = setInterval(async () => {
token.set(await auth0.getTokenSilently());
const { id_token } = await auth0.getTokenSilently({
authorizationParams: {
redirect_uri: window.location.origin
},
detailedResponse: true
});
token.set(id_token);
}, refreshRate);
}
// });
Expand Down
67 changes: 67 additions & 0 deletions src/components/ToggleTheme.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<script lang="ts">
import Button from './Button.svelte';
let theme = $state<string | null>(null);
const toggleTheme = () => {
const html = document.querySelector('html');
const themeData = html?.getAttribute('data-theme');
let nextTheme;
switch (themeData) {
case 'dark':
nextTheme = 'light';
break;
case 'light':
nextTheme = null;
break;
default:
nextTheme = 'dark';
break;
}
theme = nextTheme;
nextTheme ? html?.setAttribute('data-theme', nextTheme) : html?.removeAttribute('data-theme');
};
</script>

<Button size="small" class="ColorToggle" variant="link" onclick={toggleTheme}>
{#if theme === 'dark'}
<svg
width="18"
height="18"
viewBox="0 0 24 24"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<title>Dark</title>
<path
d="M21.996 12.882c0.022-0.233-0.038-0.476-0.188-0.681-0.325-0.446-0.951-0.544-1.397-0.219-0.95 0.693-2.060 1.086-3.188 1.162-1.368 0.092-2.765-0.283-3.95-1.158-1.333-0.985-2.139-2.415-2.367-3.935s0.124-3.124 1.109-4.456c0.142-0.191 0.216-0.435 0.191-0.691-0.053-0.55-0.542-0.952-1.092-0.898-2.258 0.22-4.314 1.18-5.895 2.651-1.736 1.615-2.902 3.847-3.137 6.386-0.254 2.749 0.631 5.343 2.266 7.311s4.022 3.313 6.772 3.567 5.343-0.631 7.311-2.266 3.313-4.022 3.567-6.772zM19.567 14.674c-0.49 1.363-1.335 2.543-2.416 3.441-1.576 1.309-3.648 2.016-5.848 1.813s-4.108-1.278-5.417-2.854-2.016-3.648-1.813-5.848c0.187-2.032 1.117-3.814 2.507-5.106 0.782-0.728 1.71-1.3 2.731-1.672-0.456 1.264-0.577 2.606-0.384 3.899 0.303 2.023 1.38 3.934 3.156 5.247 1.578 1.167 3.448 1.668 5.272 1.545 0.752-0.050 1.496-0.207 2.21-0.465z"
></path>
</svg>
{:else if theme === 'light'}
<svg
width="18"
height="18"
viewBox="0 0 24 24"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<title>Light</title>
<path
d="M18 12c0-1.657-0.673-3.158-1.757-4.243s-2.586-1.757-4.243-1.757-3.158 0.673-4.243 1.757-1.757 2.586-1.757 4.243 0.673 3.158 1.757 4.243 2.586 1.757 4.243 1.757 3.158-0.673 4.243-1.757 1.757-2.586 1.757-4.243zM16 12c0 1.105-0.447 2.103-1.172 2.828s-1.723 1.172-2.828 1.172-2.103-0.447-2.828-1.172-1.172-1.723-1.172-2.828 0.447-2.103 1.172-2.828 1.723-1.172 2.828-1.172 2.103 0.447 2.828 1.172 1.172 1.723 1.172 2.828zM11 1v2c0 0.552 0.448 1 1 1s1-0.448 1-1v-2c0-0.552-0.448-1-1-1s-1 0.448-1 1zM11 21v2c0 0.552 0.448 1 1 1s1-0.448 1-1v-2c0-0.552-0.448-1-1-1s-1 0.448-1 1zM3.513 4.927l1.42 1.42c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414l-1.42-1.42c-0.391-0.391-1.024-0.391-1.414 0s-0.391 1.024 0 1.414zM17.653 19.067l1.42 1.42c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414l-1.42-1.42c-0.391-0.391-1.024-0.391-1.414 0s-0.391 1.024 0 1.414zM1 13h2c0.552 0 1-0.448 1-1s-0.448-1-1-1h-2c-0.552 0-1 0.448-1 1s0.448 1 1 1zM21 13h2c0.552 0 1-0.448 1-1s-0.448-1-1-1h-2c-0.552 0-1 0.448-1 1s0.448 1 1 1zM4.927 20.487l1.42-1.42c0.391-0.391 0.391-1.024 0-1.414s-1.024-0.391-1.414 0l-1.42 1.42c-0.391 0.391-0.391 1.024 0 1.414s1.024 0.391 1.414 0zM19.067 6.347l1.42-1.42c0.391-0.391 0.391-1.024 0-1.414s-1.024-0.391-1.414 0l-1.42 1.42c-0.391 0.391-0.391 1.024 0 1.414s1.024 0.391 1.414 0z"
></path>
</svg>
{:else}
<svg
width="18"
height="18"
viewBox="0 0 24 24"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<title>System</title>
<path
d="M6 5h12c0.276 0 0.525 0.111 0.707 0.293s0.293 0.431 0.293 0.707v12c0 0.276-0.111 0.525-0.293 0.707s-0.431 0.293-0.707 0.293h-12c-0.276 0-0.525-0.111-0.707-0.293s-0.293-0.431-0.293-0.707v-12c0-0.276 0.111-0.525 0.293-0.707s0.431-0.293 0.707-0.293zM9 8c-0.552 0-1 0.448-1 1v6c0 0.552 0.448 1 1 1h6c0.552 0 1-0.448 1-1v-6c0-0.552-0.448-1-1-1zM10 10h4v4h-4zM1 15h2v3c0 0.828 0.337 1.58 0.879 2.121s1.293 0.879 2.121 0.879h2v2c0 0.552 0.448 1 1 1s1-0.448 1-1v-2h4v2c0 0.552 0.448 1 1 1s1-0.448 1-1v-2h2c0.828 0 1.58-0.337 2.121-0.879s0.879-1.293 0.879-2.121v-3h2c0.552 0 1-0.448 1-1s-0.448-1-1-1h-2v-3h2c0.552 0 1-0.448 1-1s-0.448-1-1-1h-2v-2c0-0.828-0.337-1.58-0.879-2.121s-1.293-0.879-2.121-0.879h-2v-2c0-0.552-0.448-1-1-1s-1 0.448-1 1v2h-4v-2c0-0.552-0.448-1-1-1s-1 0.448-1 1v2h-2c-0.828 0-1.58 0.337-2.121 0.879s-0.879 1.293-0.879 2.121v2h-2c-0.552 0-1 0.448-1 1s0.448 1 1 1h2v3h-2c-0.552 0-1 0.448-1 1s0.448 1 1 1z"
></path>
</svg>
{/if}
</Button>
Loading

0 comments on commit 5f94ba7

Please sign in to comment.