Skip to content

Commit

Permalink
fix(silentsignin): recover missing commit (#734)
Browse files Browse the repository at this point in the history
  • Loading branch information
guillaume-chervet authored Mar 22, 2022
1 parent a6591de commit e77191e
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 9 deletions.
2 changes: 1 addition & 1 deletion packages/context/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@axa-fr/react-oidc-context",
"version": "4.4.0-alpha.0",
"version": "4.5.0-alpha.0",
"private": false,
"main": "dist/index.js",
"jsnext:main": "dist/index.js",
Expand Down
5 changes: 3 additions & 2 deletions packages/context/src/MultiAuth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ if(!sessionStorage.configurationName){
export const MultiAuthContainer = () => {
const [configurationName, setConfigurationName] = useState(sessionStorage.configurationName);
const callBack = window.location.origin+"/multi-auth/authentification/callback2";
const silent_redirect_uri = window.location.origin+"/multi-auth/authentification/silent-callback2";
const configurations = {
"config_1": {...configurationIdentityServer, redirect_uri:callBack},
"config_2": {...configurationIdentityServer, redirect_uri:callBack, scope: 'openid profile email api'}
"config_1": {...configurationIdentityServer, redirect_uri:callBack, silent_redirect_uri},
"config_2": {...configurationIdentityServer, redirect_uri:callBack, silent_redirect_uri, scope: 'openid profile email api'}
}
const handleConfigurationChange = (event) => {
const configurationName = event.target.value;
Expand Down
1 change: 1 addition & 0 deletions packages/context/src/configurations.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const configurationIdentityServer = {
client_id: 'interactive.public.short', // interactive.public.short
redirect_uri: window.location.origin+'/authentication/callback', // http://localhost:4200/authentication/callback
silent_redirect_uri: window.location.origin+'/authentication/silent-callback',
scope: 'openid profile email api offline_access',
authority: 'https://demo.identityserver.io',
refresh_time_before_tokens_expiration_in_second: 70,
Expand Down
3 changes: 2 additions & 1 deletion packages/context/src/oidc/OidcProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ sessionLostComponent=SessionLost }) => {
<LoadingComponent/>
) : (
<>
<OidcRoutes redirect_uri={configuration.redirect_uri}
<OidcRoutes redirect_uri={configuration.redirect_uri}
silent_redirect_uri={configuration.silent_redirect_uri}
callbackSuccessComponent={callbackSuccessComponent}
callbackErrorComponent={callbackErrorComponent}
authenticatingComponent={authenticatingComponent}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React, { useEffect, useState, PropsWithChildren} from 'react';
import Oidc from "../../vanilla/oidc";
import {OidcSecure} from "../../OidcSecure";

const CallBak = ({configurationName}) =>{
const getOidc = Oidc.get;
useEffect(() => {
let isMounted = true;
const playCallbackAsync = async () => {
const oidc = getOidc(configurationName);
oidc.silentSigninCallbackFromIFrame();
};
playCallbackAsync();
return () => {
isMounted = false;
};
},[]);

return <></>;
}

const CallbackManager: PropsWithChildren<any> = ({configurationName }) => {
return <OidcSecure>
<CallBak configurationName={configurationName}/>
</OidcSecure>;
};

export default CallbackManager;
9 changes: 9 additions & 0 deletions packages/context/src/oidc/core/routes/OidcRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { ComponentType, FC, PropsWithChildren, useEffect, useState } from
import PropTypes from 'prop-types';
import { getPath } from './route-utils';
import CallbackComponent from '../default-component/Callback.component';
import SilentCallbackComponent from "../default-component/SilentCallback.component";
import ServiceWorkerInstall from "../default-component/ServiceWorkerInstall.component";

const propTypes = {
Expand All @@ -20,13 +21,15 @@ type OidcRoutesProps = {
authenticatingComponent?: ComponentType;
configurationName:string;
redirect_uri: string;
silent_redirect_uri?: string;
};

const OidcRoutes: FC<PropsWithChildren<OidcRoutesProps>> = ({
callbackErrorComponent,
callbackSuccessComponent,
authenticatingComponent,
redirect_uri,
silent_redirect_uri,
children, configurationName
}) => {
// This exist because in next.js window outside useEffect is null
Expand All @@ -43,6 +46,12 @@ const OidcRoutes: FC<PropsWithChildren<OidcRoutesProps>> = ({

const callbackPath = getPath(redirect_uri);

if(silent_redirect_uri){
if(path === getPath(silent_redirect_uri)){
return <SilentCallbackComponent configurationName={configurationName} />
}
}

switch (path) {
case callbackPath:
return <CallbackComponent callBackError={callbackErrorComponent} callBackSuccess={callbackSuccessComponent} configurationName={configurationName} />;
Expand Down
8 changes: 5 additions & 3 deletions packages/context/src/oidc/vanilla/initWorker.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
function get_browser() {
import timer from "./timer"

function get_browser() {
let ua = navigator.userAgent, tem,
M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
if(/trident/i.test(M[1])){
Expand Down Expand Up @@ -30,8 +32,8 @@

let keepAliveServiceWorkerTimeoutId = null;

const sleepAsync = (milliseconds) => {
return new Promise(resolve => setTimeout(resolve, milliseconds))
export const sleepAsync = (milliseconds) => {
return new Promise(resolve => timer.setTimeout(resolve, milliseconds))
}

const keepAlive = () => {
Expand Down
72 changes: 71 additions & 1 deletion packages/context/src/oidc/vanilla/oidc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
TokenRequest
} from '@openid/appauth';
import {NoHashQueryStringUtils} from './noHashQueryStringUtils';
import {initWorkerAsync} from './initWorker'
import {initWorkerAsync, sleepAsync} from './initWorker'
import {MemoryStorageBackend} from "./memoryStorageBackend";
import {initSession} from "./initSession";
import timer from './timer';
Expand Down Expand Up @@ -50,6 +50,7 @@ export interface StringMap {
export type Configuration = {
client_id: string,
redirect_uri: string,
silent_redirect_uri?:string,
scope: string,
authority: string,
refresh_time_before_tokens_expiration_in_second?: number,
Expand Down Expand Up @@ -168,8 +169,13 @@ const eventNames = {
tryKeepExistingSessionAsync_begin: "tryKeepExistingSessionAsync_begin",
tryKeepExistingSessionAsync_end: "tryKeepExistingSessionAsync_end",
tryKeepExistingSessionAsync_error: "tryKeepExistingSessionAsync_error",
silentSigninAsync_begin: "silentSigninAsync_begin",
silentSigninAsync_end: "silentSigninAsync_end",
silentSigninAsync_error: "silentSigninAsync_error",
}

let isSilentSignin = false;

export class Oidc {
public configuration: Configuration;
public userInfo: null;
Expand Down Expand Up @@ -224,7 +230,63 @@ export class Oidc {
return oidcDatabase[name];
}
static eventNames = eventNames;

silentSigninCallbackFromIFrame(){
window.top.postMessage('oidc_tokens:' + JSON.stringify(this.tokens), window.location.origin);
}
async silentSigninAsync() {
if (!this.configuration.silent_redirect_uri) {
return Promise.resolve(null);
}
while (isSilentSignin) {
console.log("while" +this.configurationName);
await sleepAsync(50);
}
isSilentSignin = true;
this.publishEvent(eventNames.silentSigninAsync_begin, {});
const link = this.configuration.silent_redirect_uri;
const iframe = document.createElement('iframe');
iframe.width = "0px";
iframe.height = "0px";
iframe.id = `${this.configurationName}_oidc_iframe`;
iframe.setAttribute("src", link);
document.body.appendChild(iframe);
const self = this;
const promise = new Promise((resolve, reject) => {
try {
let isResolved = false;
window.onmessage = function (e) {

if (e.data && typeof (e.data) === "string" && e.data.startsWith('oidc_tokens:')) {
console.log("ici" +self.configurationName);
if (!isResolved) {
self.publishEvent(eventNames.silentSigninAsync_end, {});
resolve(JSON.parse(e.data.replace('oidc_tokens:', '')));
iframe.remove();
isResolved = true;
isSilentSignin = false;
}
}
};

setTimeout(() => {
if (!isResolved) {
reject("timeout");
self.publishEvent(eventNames.silentSigninAsync_error, new Error("timeout"));
iframe.remove();
isResolved = true;
isSilentSignin = false;
}
}, 4000);
} catch (e) {
iframe.remove();
reject(e);
self.publishEvent(eventNames.silentSigninAsync_error, e);
isSilentSignin = false;
}
});
return promise;
}
async initAsync(authority) {
const oidcServerConfiguration = await AuthorizationServiceConfiguration.fetchFromIssuer(authority, new FetchRequestor());
return oidcServerConfiguration;
Expand Down Expand Up @@ -432,6 +494,14 @@ export class Oidc {
return token_response;
} catch(exception) {
console.error(exception);
const silent_token_response =await this.silentSigninAsync();
if(silent_token_response){
console.log("tokens" +this.configurationName);
console.log(silent_token_response);

return silent_token_response;
}

this.publishEvent( silentEvent ? eventNames.refreshTokensAsync_silent_error :eventNames.refreshTokensAsync_error, exception);
return null;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/vanilla/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@axa-fr/vanilla-oidc",
"version": "4.4.0",
"version": "4.5.0-alpha.0",
"private": false,
"main": "dist/index.js",
"jsnext:main": "dist/index.js",
Expand Down

0 comments on commit e77191e

Please sign in to comment.