mirror of
https://github.com/TECHNOFAB11/svelte-oidc.git
synced 2025-12-11 23:50:06 +01:00
fix: context must be loaded on initialization
svelte 3.25 and later won't let you call getContext and setContext outside of component initialization. This means you need to implement components inside the Auth0Context that getContext on initialization then pass them to functions BREAKING CHANGE: function signature for login, logout, and refreshToken
This commit is contained in:
parent
c35df91c73
commit
e4cf984082
8 changed files with 766 additions and 500 deletions
1177
package-lock.json
generated
1177
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@dopry/svelte-oidc",
|
"name": "@dopry/svelte-oidc",
|
||||||
"version": "0.3.1",
|
"version": "1.0.0",
|
||||||
"repository": "https://github.com/dopry/svelte-oidc",
|
"repository": "https://github.com/dopry/svelte-oidc",
|
||||||
"description": "Svelte OIDC Component Library",
|
"description": "Svelte OIDC Component Library",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
|
@ -71,8 +71,8 @@
|
||||||
"rollup-plugin-terser": "7.0.2",
|
"rollup-plugin-terser": "7.0.2",
|
||||||
"sirv-cli": "1.0.6",
|
"sirv-cli": "1.0.6",
|
||||||
"start-server-and-test": "1.12.0",
|
"start-server-and-test": "1.12.0",
|
||||||
"svelte": "3.24.1",
|
"svelte": "3.35.0",
|
||||||
"svelte-highlight": "0.6.2",
|
"svelte-highlight": "0.7.1",
|
||||||
"svelte-preprocess": "4.0.11"
|
"svelte-preprocess": "4.6.9"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,9 @@ import { json } from 'svelte-highlight/languages';
|
||||||
import { arduinoLight as highlightTheme } from "svelte-highlight/styles";
|
import { arduinoLight as highlightTheme } from "svelte-highlight/styles";
|
||||||
import {
|
import {
|
||||||
OidcContext,
|
OidcContext,
|
||||||
|
LoginButton,
|
||||||
|
LogoutButton,
|
||||||
|
RefreshTokenButton,
|
||||||
authError,
|
authError,
|
||||||
idToken,
|
idToken,
|
||||||
accessToken,
|
accessToken,
|
||||||
|
|
@ -27,10 +30,9 @@ import {
|
||||||
redirect_uri="process.env.OIDC_REDIRECT_URI"
|
redirect_uri="process.env.OIDC_REDIRECT_URI"
|
||||||
post_logout_redirect_uri="process.env.OIDC_POST_LOGOUT_REDIRECT_URI"
|
post_logout_redirect_uri="process.env.OIDC_POST_LOGOUT_REDIRECT_URI"
|
||||||
>
|
>
|
||||||
|
<LoginButton>Login</LoginButton>
|
||||||
<button class="btn" on:click|preventDefault='{() => login() }'>Login</button>
|
<LogoutButton>Logout</LogoutButton>
|
||||||
<button class="btn" on:click|preventDefault='{() => logout() }'>Logout</button>
|
<RefreshTokenButton>refreshToken</RefreshTokenButton>
|
||||||
<button class="btn" on:click|preventDefault='{() => refreshToken() }'>refreshToken</button>
|
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr><th style="width: 20%;">store</th><th style="width: 80%;">value</th></tr>
|
<tr><th style="width: 20%;">store</th><th style="width: 80%;">value</th></tr>
|
||||||
|
|
|
||||||
14
src/components/LoginButton.svelte
Normal file
14
src/components/LoginButton.svelte
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
<script>
|
||||||
|
import { getContext } from 'svelte';
|
||||||
|
import {
|
||||||
|
OIDC_CONTEXT_CLIENT_PROMISE,
|
||||||
|
OIDC_CONTEXT_REDIRECT_URI,
|
||||||
|
login,
|
||||||
|
} from './OidcContext.svelte';
|
||||||
|
|
||||||
|
const oidcPromise = getContext(OIDC_CONTEXT_CLIENT_PROMISE)
|
||||||
|
export let callback_url = getContext(OIDC_CONTEXT_REDIRECT_URI)
|
||||||
|
export let preserveRoute
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button class="btn" on:click|preventDefault='{() => login(oidcPromise, preserveRoute, callback_url) }'><slot></slot></button>
|
||||||
13
src/components/LogoutButton.svelte
Normal file
13
src/components/LogoutButton.svelte
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
<script>
|
||||||
|
import { getContext } from 'svelte';
|
||||||
|
import {
|
||||||
|
OIDC_CONTEXT_CLIENT_PROMISE,
|
||||||
|
OIDC_CONTEXT_POST_LOGOUT_REDIRECT_URI,
|
||||||
|
logout,
|
||||||
|
} from './OidcContext.svelte';
|
||||||
|
|
||||||
|
const oidcPromise = getContext(OIDC_CONTEXT_CLIENT_PROMISE)
|
||||||
|
export let logout_url = getContext(OIDC_CONTEXT_POST_LOGOUT_REDIRECT_URI)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button class="btn" on:click|preventDefault='{() => logout(oidcPromise, logout_url) }'><slot></slot></button>
|
||||||
|
|
@ -28,12 +28,14 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refresh the accessToken using the silentRenew method (hidden iframe)
|
* Refresh the accessToken using the silentRenew method (hidden iframe)
|
||||||
|
*
|
||||||
|
* @param {Promise<UserManager>} oidcPromise
|
||||||
* @return bool indicated whether the token was refreshed, if false error will be set
|
* @return bool indicated whether the token was refreshed, if false error will be set
|
||||||
* in the authError store.
|
* in the authError store.
|
||||||
*/
|
*/
|
||||||
export async function refreshToken() {
|
export async function refreshToken(oidcPromise) {
|
||||||
try {
|
try {
|
||||||
const oidc = await getContext(OIDC_CONTEXT_CLIENT_PROMISE);
|
const oidc = await oidcPromise
|
||||||
await oidc.signinSilent();
|
await oidc.signinSilent();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -47,12 +49,13 @@
|
||||||
/**
|
/**
|
||||||
* Initiate Register/Login flow.
|
* Initiate Register/Login flow.
|
||||||
*
|
*
|
||||||
|
* @param {Promise<UserManager>} oidcPromise
|
||||||
* @param {boolean} preserveRoute - store current location so callback handler will navigate back to it.
|
* @param {boolean} preserveRoute - store current location so callback handler will navigate back to it.
|
||||||
* @param {string} callback_url - explicit path to use for the callback.
|
* @param {string} callback_url - explicit path to use for the callback.
|
||||||
*/
|
*/
|
||||||
export async function login(preserveRoute = true, callback_url = null) {
|
export async function login(oidcPromise, preserveRoute = true, callback_url = null) {
|
||||||
const oidc = await getContext(OIDC_CONTEXT_CLIENT_PROMISE);
|
const oidc = await oidcPromise;
|
||||||
const redirect_uri = callback_url || getContext(OIDC_CONTEXT_REDIRECT_URI) || window.location.href;
|
const redirect_uri = callback_url || window.location.href;
|
||||||
|
|
||||||
// try to keep the user on the same page from which they triggered login. If set to false should typically
|
// try to keep the user on the same page from which they triggered login. If set to false should typically
|
||||||
// cause redirect to /.
|
// cause redirect to /.
|
||||||
|
|
@ -67,12 +70,13 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log out the current user.
|
* Log out the current user.
|
||||||
*
|
*
|
||||||
|
* @param {Promise<UserManager>} oidcPromise
|
||||||
* @param {string} logout_url - specify the url to return to after login.
|
* @param {string} logout_url - specify the url to return to after login.
|
||||||
*/
|
*/
|
||||||
export async function logout(logout_url = null) {
|
export async function logout(oidcPromise, logout_url = null) {
|
||||||
const oidc = await getContext(OIDC_CONTEXT_CLIENT_PROMISE);
|
const oidc = await oidcPromise;
|
||||||
const returnTo = logout_url || getContext(OIDC_CONTEXT_POST_LOGOUT_REDIRECT_URI) || window.location.href;
|
const returnTo = logout_url || window.location.href;
|
||||||
oidc.signoutRedirect({ returnTo });
|
oidc.signoutRedirect({ returnTo });
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -120,9 +124,8 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// userManager needs to be wrapped in a promise and the work
|
// does userManager needs to be wrapped in a promise? or is this a left over to maintain
|
||||||
// needs to be done onMount to otherwise there is an
|
// symmetry with the @dopry/svelte-auth0 auth0 implementation
|
||||||
// Error: Function called outside component initialization
|
|
||||||
let oidcPromise = Promise.resolve(userManager);
|
let oidcPromise = Promise.resolve(userManager);
|
||||||
setContext(OIDC_CONTEXT_CLIENT_PROMISE, oidcPromise);
|
setContext(OIDC_CONTEXT_CLIENT_PROMISE, oidcPromise);
|
||||||
|
|
||||||
|
|
@ -132,7 +135,7 @@
|
||||||
// Use 'error' and 'code' to test if the component is being executed as a part of a login callback. If we're not
|
// Use 'error' and 'code' to test if the component is being executed as a part of a login callback. If we're not
|
||||||
// running in a login callback, and the user isn't logged in, see if we can capture their existing session.
|
// running in a login callback, and the user isn't logged in, see if we can capture their existing session.
|
||||||
if (!params.has('error') && !params.has('code') && !$isAuthenticated) {
|
if (!params.has('error') && !params.has('code') && !$isAuthenticated) {
|
||||||
refreshToken();
|
refreshToken(oidcPromise);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleOnMount() {
|
async function handleOnMount() {
|
||||||
|
|
@ -165,6 +168,7 @@
|
||||||
// what the uris loook like. I fear this may be problematic in other auth flows in the future.
|
// what the uris loook like. I fear this may be problematic in other auth flows in the future.
|
||||||
else if (params.has('state')) {
|
else if (params.has('state')) {
|
||||||
const response = await oidc.signinCallback();
|
const response = await oidc.signinCallback();
|
||||||
|
console.log('oidc.signinCallback::response', response)
|
||||||
}
|
}
|
||||||
isLoading.set(false);
|
isLoading.set(false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
11
src/components/RefreshTokenButton.svelte
Normal file
11
src/components/RefreshTokenButton.svelte
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
<script>
|
||||||
|
import { getContext } from 'svelte';
|
||||||
|
import {
|
||||||
|
OIDC_CONTEXT_CLIENT_PROMISE,
|
||||||
|
refreshToken,
|
||||||
|
} from './OidcContext.svelte';
|
||||||
|
|
||||||
|
const oidcPromise = getContext(OIDC_CONTEXT_CLIENT_PROMISE)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button class="btn" on:click|preventDefault='{() => refreshToken(oidcPromise) }'><slot></slot></button>
|
||||||
|
|
@ -10,4 +10,7 @@ export {
|
||||||
refreshToken,
|
refreshToken,
|
||||||
userInfo,
|
userInfo,
|
||||||
} from './OidcContext.svelte';
|
} from './OidcContext.svelte';
|
||||||
|
export { default as LoginButton} from './LoginButton.svelte'
|
||||||
|
export { default as LogoutButton} from './LogoutButton.svelte'
|
||||||
|
export { default as RefreshTokenButton} from './RefreshTokenButton.svelte'
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue