Skip to content

Instantly share code, notes, and snippets.

@DirkWolthuis
Created December 7, 2020 18:45
Show Gist options
  • Save DirkWolthuis/055f7e5f4dee27782a11fb4d1b49f139 to your computer and use it in GitHub Desktop.
Save DirkWolthuis/055f7e5f4dee27782a11fb4d1b49f139 to your computer and use it in GitHub Desktop.
Svelte context + store example
<script lang="ts">
import createAuth0Client, { Auth0Client } from "@auth0/auth0-spa-js";
import { onMount, setContext } from "svelte";
import { writable } from "svelte/store";
const isLoading = writable(true);
const isAuthenticated = writable(false);
const authToken = writable("");
const userInfo = writable({});
const authError = writable(null);
const AUTH_KEY = "AUTHENTICATION";
const authService = writable<Auth0Client>(null);
const refreshRate = 10 * 60 * 60 * 1000;
let auth0: Auth0Client = null;
let intervalId = undefined;
onMount(async () => {
const auth0 = await createAuth0Client({
domain: __dndtables.env.AUTH0_DOMAIN,
client_id: __dndtables.env.AUTH0_CLIENT_ID,
});
authService.set(auth0);
// Not all browsers support this, please program defensively!
const params = new URLSearchParams(window.location.search);
// Check if something went wrong during login redirect
// and extract the error message
if (params.has("error")) {
authError.set(new Error(params.get("error_description")));
}
// if code then login success
if (params.has("code")) {
// Let the Auth0 SDK do it's stuff - save some state, etc.
await auth0.handleRedirectCallback();
// Can be smart here and redirect to original path instead of root
window.history.replaceState({}, document.title, "/");
authError.set(null);
}
const _isAuthenticated = await auth0.isAuthenticated();
isAuthenticated.set(_isAuthenticated);
if (_isAuthenticated) {
// while on it, fetch the user info
userInfo.set(await auth0.getUser());
// 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();
authToken.set(token);
// refresh token after specific period or things will stop
// working. Useful for long-lived apps like dashboards.
intervalId = setInterval(async () => {
authToken.set(await auth0.getTokenSilently());
}, refreshRate);
}
isLoading.set(false);
// clear token refresh interval on component unmount
return () => {
intervalId && clearInterval(intervalId);
};
});
// Provide a redirect page if you need.
// It must be whitelisted in Auth0. I think.
const login = async () => {
let authInstance: Auth0Client;
const unsubscribe = authService.subscribe(auth => authInstance = auth);
await authInstance.loginWithRedirect({
redirect_uri: window.location.origin,
prompt: "login", // Force login prompt. No silence auth for you!
});
unsubscribe();
};
const logout = () => {
let authInstance: Auth0Client;
const unsubscribe = authService.subscribe(auth => authInstance = auth);
authInstance.logout({
returnTo: window.location.origin,
});
unsubscribe();
};
const auth = {
isLoading,
isAuthenticated,
authToken,
authError,
login,
logout,
userInfo,
};
// Put everything in context so that child
// components can access the state
setContext(AUTH_KEY, auth);
</script>
<slot />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment