mirror of
https://github.com/TECHNOFAB11/svelte-oidc.git
synced 2025-12-11 23:50:06 +01:00
chore: consolidate into single component file.
This commit is contained in:
parent
701668b662
commit
215a0a443f
3 changed files with 131 additions and 129 deletions
|
|
@ -1,55 +1,108 @@
|
||||||
<script>
|
<script context="module">
|
||||||
|
import { writable } from 'svelte/store';
|
||||||
|
import { getContext } from 'svelte';
|
||||||
import oidcClient from 'oidc-client';
|
import oidcClient from 'oidc-client';
|
||||||
const { UserManager } = oidcClient;
|
const { UserManager } = oidcClient;
|
||||||
import { onMount, onDestroy, setContext, getContext } from 'svelte';
|
import { onMount, onDestroy, setContext } from 'svelte';
|
||||||
import {
|
|
||||||
OIDC_CONTEXT_REDIRECT_URI,
|
|
||||||
OIDC_CONTEXT_CLIENT_PROMISE,
|
|
||||||
OIDC_CONTEXT_POST_LOGOUT_REDIRECT_URI,
|
|
||||||
idToken,
|
|
||||||
accessToken,
|
|
||||||
isAuthenticated,
|
|
||||||
isLoading,
|
|
||||||
authError,
|
|
||||||
userInfo,
|
|
||||||
} from './oidc';
|
|
||||||
|
|
||||||
// props.
|
/**
|
||||||
export let issuer;
|
* Stores
|
||||||
export let client_id;
|
*/
|
||||||
export let redirect_uri;
|
export const isLoading = writable(true);
|
||||||
export let post_logout_redirect_uri;
|
export const isAuthenticated = writable(false);
|
||||||
export let metadata = {};
|
export const accessToken = writable('');
|
||||||
|
export const idToken = writable('');
|
||||||
|
export const userInfo = writable({});
|
||||||
|
export const authError = writable(null);
|
||||||
|
|
||||||
setContext(OIDC_CONTEXT_REDIRECT_URI, redirect_uri);
|
/**
|
||||||
setContext(OIDC_CONTEXT_POST_LOGOUT_REDIRECT_URI, post_logout_redirect_uri);
|
* Context Keys
|
||||||
|
*
|
||||||
|
* using an object literal means the keys are guaranteed not to conflict in any circumstance (since an object only has
|
||||||
|
* referential equality to itself, i.e. {} !== {} whereas "x" === "x"), even when you have multiple different contexts
|
||||||
|
* operating across many component layers.
|
||||||
|
*/
|
||||||
|
export const OIDC_CONTEXT_CLIENT_PROMISE = {};
|
||||||
|
export const OIDC_CONTEXT_REDIRECT_URI = {};
|
||||||
|
export const OIDC_CONTEXT_POST_LOGOUT_REDIRECT_URI = {};
|
||||||
|
|
||||||
// getContext doesn't seem to return a value in OnMount, so we'll pass the oidcPromise around by reference.
|
/**
|
||||||
const settings = {
|
* Refresh the accessToken store.
|
||||||
authority: issuer,
|
*/
|
||||||
client_id,
|
export async function refreshToken() {
|
||||||
response_type: 'id_token token',
|
const oidc = await getContext(OIDC_CONTEXT_CLIENT_PROMISE);
|
||||||
redirect_uri,
|
await oidc.signinSilent();
|
||||||
post_logout_redirect_uri,
|
}
|
||||||
response_type: 'code',
|
|
||||||
scope: 'openid profile email',
|
/**
|
||||||
automaticSilentRenew: true,
|
* Initiate Register/Login flow.
|
||||||
|
*
|
||||||
|
* @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.
|
||||||
|
*/
|
||||||
|
export async function login(preserveRoute = true, callback_url = null) {
|
||||||
|
const oidc = await getContext(OIDC_CONTEXT_CLIENT_PROMISE);
|
||||||
|
const redirect_uri = callback_url || getContext(OIDC_CONTEXT_REDIRECT_URI) || window.location.href;
|
||||||
|
|
||||||
|
// try to keep the user on the same page from which they triggered login. If set to false should typically
|
||||||
|
// cause redirect to /.
|
||||||
|
const appState = preserveRoute
|
||||||
|
? {
|
||||||
|
pathname: window.location.pathname,
|
||||||
|
search: window.location.search,
|
||||||
|
}
|
||||||
|
: {};
|
||||||
|
await oidc.signinRedirect({ redirect_uri, appState });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log out the current user.
|
||||||
|
*
|
||||||
|
* @param {string} logout_url - specify the url to return to after login.
|
||||||
|
*/
|
||||||
|
export async function logout(logout_url = null) {
|
||||||
|
const oidc = await getContext(OIDC_CONTEXT_CLIENT_PROMISE);
|
||||||
|
const returnTo = logout_url || getContext(OIDC_CONTEXT_POST_LOGOUT_REDIRECT_URI) || window.location.href;
|
||||||
|
oidc.signoutRedirect({ returnTo });
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// props.
|
||||||
|
export let issuer;
|
||||||
|
export let client_id;
|
||||||
|
export let redirect_uri;
|
||||||
|
export let post_logout_redirect_uri;
|
||||||
|
export let metadata = {};
|
||||||
|
|
||||||
|
setContext(OIDC_CONTEXT_REDIRECT_URI, redirect_uri);
|
||||||
|
setContext(OIDC_CONTEXT_POST_LOGOUT_REDIRECT_URI, post_logout_redirect_uri);
|
||||||
|
|
||||||
|
const settings = {
|
||||||
|
authority: issuer,
|
||||||
|
client_id,
|
||||||
|
// response_type: 'id_token token',
|
||||||
|
redirect_uri,
|
||||||
|
post_logout_redirect_uri,
|
||||||
|
response_type: 'code',
|
||||||
|
scope: 'openid profile email',
|
||||||
|
automaticSilentRenew: true,
|
||||||
metadata
|
metadata
|
||||||
};
|
};
|
||||||
|
|
||||||
const userManager = new UserManager(settings);
|
const userManager = new UserManager(settings);
|
||||||
userManager.events.addUserLoaded(function (user) {
|
userManager.events.addUserLoaded(function (user) {
|
||||||
isAuthenticated.set(true);
|
isAuthenticated.set(true);
|
||||||
accessToken.set(user.access_token);
|
accessToken.set(user.access_token);
|
||||||
idToken.set(user.id_token);
|
idToken.set(user.id_token);
|
||||||
userInfo.set(user.profile);
|
userInfo.set(user.profile);
|
||||||
});
|
});
|
||||||
|
|
||||||
userManager.events.addUserUnloaded(function () {
|
userManager.events.addUserUnloaded(function () {
|
||||||
isAuthenticated.set(false);
|
isAuthenticated.set(false);
|
||||||
idToken.set('');
|
idToken.set('');
|
||||||
accessToken.set('');
|
accessToken.set('');
|
||||||
userInfo.set({});
|
userInfo.set({});
|
||||||
});
|
});
|
||||||
|
|
||||||
userManager.events.addSilentRenewError(function (e) {
|
userManager.events.addSilentRenewError(function (e) {
|
||||||
|
|
@ -61,40 +114,40 @@
|
||||||
setContext(OIDC_CONTEXT_CLIENT_PROMISE, oidcPromise);
|
setContext(OIDC_CONTEXT_CLIENT_PROMISE, oidcPromise);
|
||||||
|
|
||||||
|
|
||||||
async function handleOnMount() {
|
async function handleOnMount() {
|
||||||
// on run onMount after oidc
|
// on run onMount after oidc
|
||||||
const oidc = await oidcPromise;
|
const oidc = await oidcPromise;
|
||||||
|
|
||||||
// Not all browsers support this, please program defensively!
|
// Not all browsers support this, please program defensively!
|
||||||
const params = new URLSearchParams(window.location.search);
|
const params = new URLSearchParams(window.location.search);
|
||||||
|
|
||||||
// Check if something went wrong during login redirect
|
// Check if something went wrong during login redirect
|
||||||
// and extract the error message
|
// and extract the error message
|
||||||
if (params.has('error')) {
|
if (params.has('error')) {
|
||||||
authError.set(new Error(params.get('error_description')));
|
authError.set(new Error(params.get('error_description')));
|
||||||
}
|
}
|
||||||
|
|
||||||
// if code then login success
|
// if code then login success
|
||||||
if (params.has('code')) {
|
if (params.has('code')) {
|
||||||
// handle the callback
|
// handle the callback
|
||||||
const response = await oidc.signinCallback();
|
const response = await oidc.signinCallback();
|
||||||
let state = (response && response.state) || {}
|
let state = (response && response.state) || {}
|
||||||
// Can be smart here and redirect to original path instead of root
|
// Can be smart here and redirect to original path instead of root
|
||||||
const url = state && state.targetUrl ? state.targetUrl : window.location.pathname;
|
const url = state && state.targetUrl ? state.targetUrl : window.location.pathname;
|
||||||
state = { ...state, isRedirectCallback: true };
|
state = { ...state, isRedirectCallback: true };
|
||||||
|
|
||||||
// redirect to the last page we were on when login was configured if it was passed.
|
// redirect to the last page we were on when login was configured if it was passed.
|
||||||
history.replaceState(state, "", url);
|
history.replaceState(state, "", url);
|
||||||
// location.href = url;
|
// location.href = url;
|
||||||
// clear errors on login.
|
// clear errors on login.
|
||||||
authError.set(null);
|
authError.set(null);
|
||||||
}
|
}
|
||||||
isLoading.set(false);
|
isLoading.set(false);
|
||||||
}
|
}
|
||||||
async function handleOnDestroy() {}
|
async function handleOnDestroy() {}
|
||||||
|
|
||||||
onMount(handleOnMount);
|
onMount(handleOnMount);
|
||||||
onDestroy(handleOnDestroy);
|
onDestroy(handleOnDestroy);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,13 @@
|
||||||
export * from './oidc'
|
export {
|
||||||
export { default as OidcContext } from './OidcContext.svelte';
|
default as OidcContext,
|
||||||
|
authError,
|
||||||
|
idToken,
|
||||||
|
accessToken,
|
||||||
|
isAuthenticated,
|
||||||
|
isLoading,
|
||||||
|
login,
|
||||||
|
logout,
|
||||||
|
refreshToken,
|
||||||
|
userInfo,
|
||||||
|
} from './OidcContext.svelte';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
import { writable } from 'svelte/store';
|
|
||||||
import { getContext } from 'svelte';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores
|
|
||||||
*/
|
|
||||||
export const isLoading = writable(true);
|
|
||||||
export const isAuthenticated = writable(false);
|
|
||||||
export const accessToken = writable('');
|
|
||||||
export const idToken = writable('');
|
|
||||||
export const userInfo = writable({});
|
|
||||||
export const authError = writable(null);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Context Keys
|
|
||||||
*
|
|
||||||
* using an object literal means the keys are guaranteed not to conflict in any circumstance (since an object only has
|
|
||||||
* referential equality to itself, i.e. {} !== {} whereas "x" === "x"), even when you have multiple different contexts
|
|
||||||
* operating across many component layers.
|
|
||||||
*/
|
|
||||||
export const OIDC_CONTEXT_CLIENT_PROMISE = {};
|
|
||||||
export const OIDC_CONTEXT_REDIRECT_URI = {};
|
|
||||||
export const OIDC_CONTEXT_POST_LOGOUT_REDIRECT_URI = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Refresh the accessToken store.
|
|
||||||
*/
|
|
||||||
export async function refreshToken() {
|
|
||||||
const oidc = await getContext(OIDC_CONTEXT_CLIENT_PROMISE)
|
|
||||||
const token = await oidc.signinSilent();
|
|
||||||
accessToken.set(token.accessToken);
|
|
||||||
idToken.set(token.idToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initiate Register/Login flow.
|
|
||||||
*
|
|
||||||
* @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.
|
|
||||||
*/
|
|
||||||
export async function login(preserveRoute = true, callback_url = null) {
|
|
||||||
const oidc = await getContext(OIDC_CONTEXT_CLIENT_PROMISE)
|
|
||||||
const redirect_uri = callback_url || getContext(OIDC_CONTEXT_REDIRECT_URI) || window.location.href;
|
|
||||||
|
|
||||||
// try to keep the user on the same page from which they triggered login. If set to false should typically
|
|
||||||
// cause redirect to /.
|
|
||||||
const appState = (preserveRoute) ? { pathname: window.location.pathname, search: window.location.search } : {}
|
|
||||||
await oidc.signinRedirect({ redirect_uri, appState });
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log out the current user.
|
|
||||||
*
|
|
||||||
* @param {string} logout_url - specify the url to return to after login.
|
|
||||||
*/
|
|
||||||
export async function logout(logout_url = null) {
|
|
||||||
const oidc = await getContext(OIDC_CONTEXT_CLIENT_PROMISE)
|
|
||||||
const returnTo = logout_url || getContext(OIDC_CONTEXT_POST_LOGOUT_REDIRECT_URI) || window.location.href;
|
|
||||||
accessToken.set('');
|
|
||||||
oidc.signoutRedirect({ returnTo });
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue