Skip to content

Commit

Permalink
set cookie domain, oidc session key, logging
Browse files Browse the repository at this point in the history
  • Loading branch information
SebastianW committed Nov 15, 2024
1 parent 2dbf428 commit a6e5426
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 46 deletions.
78 changes: 36 additions & 42 deletions libs/oidc/src/services/oidc.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { OidcStrategy } from '../strategies';
import { loginPopupTemplate } from '../templates/login-popup.hbs';
import { SSRPagesService } from './ssr-pages.service';
import passport = require('passport');
// const url = require('url');

const _loginCallbackPath = 'login/callback';

Expand All @@ -23,7 +22,7 @@ export class OidcService implements OnModuleInit {
#instanceID: string;
#oidc_redirect_uri: string;
#region: string;
// #sessionKey: string;
#sessionKey: string;
isMultitenant: boolean = false;
strategy: any;
idpInfos: {
Expand All @@ -43,7 +42,7 @@ export class OidcService implements OnModuleInit {
this.isMultitenant = !!this.options.issuerOrigin;
this.#instanceID = configService.get('SERVER_INSTANCE_ID');
this.#region = configService.get('REGION_NAME');
// this.#sessionKey = `oidc:${configService.get('APIM_BASE_URL').replace('https://', '')}`;
this.#sessionKey = `oidc:${configService.get('APIM_BASE_URL').replace('https://', '')}`;
this.#oidc_redirect_uri = configService.get('OIDC_REDIRECT_URI') ? `${configService.get('OIDC_REDIRECT_URI')}` : `${this.options.origin}`;
}

Expand Down Expand Up @@ -75,6 +74,7 @@ export class OidcService implements OnModuleInit {
break;
}
}
this.logger.log(JSON.stringify({ name: 'ISSUER DISCOVER', region: this.#region }));
const trustIssuer = await Issuer.discover(issuer);
const client = new trustIssuer.Client(clientMetadata);
const tokenStore = await trustIssuer.keystore();
Expand All @@ -90,9 +90,6 @@ export class OidcService implements OnModuleInit {
this.options.authParams.redirect_uri = `${this.#oidc_redirect_uri}/${_loginCallbackPath}`;
this.options.authParams.nonce = this.options.authParams.nonce === 'true' ? uuid() : this.options.authParams.nonce;

// const hostname = url.parse(trustIssuer.issuer).hostname;
// this.#sessionKey = this.#buildSessionKey({ key: this.#sessionKey, hostname });

strategy = new OidcStrategy(this, key, channelType);
this.idpInfos[key].strategy = strategy;

Expand Down Expand Up @@ -131,7 +128,7 @@ export class OidcService implements OnModuleInit {
}

async login(@Req() req: Request, @Res() res: Response, @Next() next: Function, @Param() params) {
this.logger.log(this.#sessionLog({ name: 'LOGIN', req, instanceID: this.#instanceID, region: this.#region }));
this.logger.log(this.#sessionLog({ name: 'LOGIN', req }));
try {
const tenantId = params.tenantId || req.session['tenant'];
const channel = this.options.channelType || params.channelType || req.session['channel'];
Expand Down Expand Up @@ -168,7 +165,7 @@ export class OidcService implements OnModuleInit {
req.session['tenant'] = tenantId;
req.session['channel'] = channel;
redirect_url = Buffer.from(JSON.stringify({ redirect_url: `${prefix}${redirect_url}`, loginpopup: loginpopup }), 'utf-8',).toString('base64');
this.logger.log(this.#sessionLog({ name: 'PRE_AUTHENTICATE', req, instanceID: this.#instanceID, region: this.#region }));
this.logger.log(this.#sessionLog({ name: 'PRE_AUTHENTICATE', req }));

passport.authenticate(
Object.create(strategy),
Expand All @@ -179,14 +176,13 @@ export class OidcService implements OnModuleInit {
},
(err, user, info) => {
if (err || !user) {
this.logger.error(this.#sessionLog({ name: 'AUTHENTICATE ERROR', req, instanceID: this.#instanceID, region: this.#region }));
this.logger.log(`AUTHENTICATE ERROR INFO`, JSON.stringify(info))
this.logger.error(this.#sessionLog({ name: 'AUTHENTICATE ERROR', req }));
return next(err || info);
}
this.logger.log(this.#sessionLog({ name: 'PRE_LOGIN_REQ', req, instanceID: this.#instanceID, region: this.#region }));
this.logger.log(this.#sessionLog({ name: 'PRE_LOGIN_REQ', req }));
req.logIn(user, err => {
if (err) {
this.logger.error(this.#sessionLog({ name: 'LOGIN_REQ ERROR', req, instanceID: this.#instanceID, region: this.#region }));
this.logger.error(this.#sessionLog({ name: 'LOGIN_REQ ERROR', req }));
return next(err);
}
this.updateSessionDuration(req);
Expand All @@ -196,52 +192,42 @@ export class OidcService implements OnModuleInit {
let url: string = state['redirect_url'];
url = !url.startsWith('/') ? `/${url}` : url;
const loginpopup = state['loginpopup'];
this.logger.log(this.#sessionLog({ name: 'PRE_REDIRECT', req, instanceID: this.#instanceID, region: this.#region }));
this.logger.log(this.#sessionLog({ name: 'PRE_REDIRECT', req }));
if (loginpopup) {
return res.send(`
<script type="text/javascript">
window.close();
</script >
`);
} else {
this.logger.log(this.#sessionLog({ name: 'REDIRECT AFTER LOGIN CALLBACK', req, instanceID: this.#instanceID, region: this.#region }));
// let url: string = state['redirect_url'];
// let redirect_url = this.#oidc_redirect_uri.replace(`-${this.#region}`, '').replace(_loginCallbackPath, '');
// url = `${redirect_url}/${url}`;
// url = !url.startsWith('/') ? `/${url}` : url;

const redirect_url = this.#oidc_redirect_uri.replace(`-${this.#region}`, '').replace(`/${_loginCallbackPath}`, '');
this.logger.log(`redirect_url: ${redirect_url}`);

// return res.redirect(redirect_url);

this.logger.log(this.#sessionLog({ name: 'AUTHENTICATION SUCCESS', req }));
if (req.get('host').includes(this.#region) === true || req.headers.host.includes(this.#region) === true) {
this.logger.log(this.#sessionLog({ name: 'AUTHENTICATION SUCCESS URL WITH REGION', req }));
const redirect_url = this.#oidc_redirect_uri.replace(`-${this.#region}`, '').replace(`/${_loginCallbackPath}`, '');
this.logger.log(`redirect_uri: ${redirect_url}`);
return res.redirect(redirect_url);
}
return res.redirect(url);
}
});
},
)(req, res, next);
}
} catch (err) {
this.logger.error(this.#sessionLog({ name: 'CATCH', req, instanceID: this.#instanceID, region: this.#region }));
this.logger.error(this.#sessionLog({ name: 'CATCH', req }));
res.status(HttpStatus.NOT_FOUND).send();
}
}

async loginCallback(@Req() req: Request, @Res() res: Response, @Next() next: Function, @Param() params) {
this.logger.log(this.#sessionLog({ name: 'LOGIN CALLBACK', req, instanceID: this.#instanceID, region: this.#region }));
// const session = req.session[this.#sessionKey];
// if (req.headers.host.includes(this.#region) === true) {
// const originalUrl = req.originalUrl;
// const redirect_url = this.#oidc_redirect_uri.replace(`-${this.#region}`, '').replace(`/${_loginCallbackPath}`, '');
// res.redirect(`${redirect_url}${originalUrl}`);


// if (Object.keys(session || {}).length === 0) {
// this.logger.log(this.#sessionLog({ name: 'SESSION EMPTY', req, instanceID: this.#instanceID, region: this.#region }));
// }
// } else {
this.logger.log(this.#sessionLog({ name: 'LOGIN CALLBACK', req }));
const session = req.session[this.#sessionKey];

if (Object.keys(session || {}).length === 0) {
// TODO: check if same region is always responding (redirect_uri.includes(this.region))
this.logger.log(this.#sessionLog({ name: 'LOGIN CALLBACK SESSION EMPTY', req }));
}
return this.login(req, res, next, params);
// }
}

async logout(@Req() req: Request, @Res() res: Response, @Param() params) {
Expand Down Expand Up @@ -276,7 +262,12 @@ export class OidcService implements OnModuleInit {
}

async refreshTokens(@Req() req: Request, @Res() res: Response, @Next() next: Function) {
this.logger.log(this.#sessionLog({ name: 'REFRESH TOKEN', req }));
const user = JSON.stringify(req.user ?? {});
this.logger.log(`REFRESH TOKEN user: ${user}`);

if (!req.isAuthenticated()) {
this.logger.log(`REFRESH TOKEN isAuthenticated: ${req.isAuthenticated()}`);
res.sendStatus(401);
return;
}
Expand All @@ -288,9 +279,12 @@ export class OidcService implements OnModuleInit {
.then(data => {
this.updateUserAuthToken(data, req);
this.updateSessionDuration(req);
this.logger.log(this.#sessionLog({ name: 'REFRESH TOKEN SUCCESS', req }));
res.sendStatus(200);
})
.catch(err => {
this.logger.log(this.#sessionLog({ name: 'REFRESH TOKEN ERROR', req }));
this.logger.log(`REFRESH TOKEN ERROR user: ${user}`);
res.status(401).send(err);
});
} else {
Expand Down Expand Up @@ -386,10 +380,10 @@ export class OidcService implements OnModuleInit {
return [tenantPrefix, channelPrefix].filter(Boolean).join('/');
}

#sessionLog({ name, req, instanceID = this.#instanceID, region = this.#region }: LogParams = {} as LogParams): string {
// const session = req.session[this.#sessionKey] ?? {}; oidc_session: ${JSON.stringify(session)},
return `${name.toLocaleUpperCase()} url: ${req.url}, method: ${req.method}, instanceID: ${instanceID}, region: ${region}`;
#sessionLog({ name, req, instanceID = this.#instanceID, region = this.#region, sessionKey = this.#sessionKey, redirectUri = this.#oidc_redirect_uri }: LogParams = {} as LogParams): string {
const session = JSON.stringify(req.session[sessionKey] ?? {});
return `${name.toLocaleUpperCase()} url: ${req.url}, method: ${req.method}, instanceID: ${instanceID}, region: ${region}, redirect_uri: ${redirectUri}, session: ${session}`;
}
}

interface LogParams { name: string, req: Request, instanceID: string, region: string };
interface LogParams { name: string, req: Request, instanceID?: string, region?: string, sessionKey?: string, redirectUri?: string };
5 changes: 1 addition & 4 deletions libs/oidc/src/utils/session/base-session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,13 @@ let session = {
maxAge: 30 * 60 * 1000, // session expires in 1hr, refreshed by `rolling: true` option.
httpOnly: true, // so that cookie can't be accessed via client-side script
secure: false,
domain: process.env.DNS_DOMAIN
//sameSite: 'lax',
},
};

// if (process.env.NODE_ENV === 'production') {
// session.cookie.secure = true; // https only
// }
// TODO: enfoce domain if 500 session:undefined will occur on same pod
// if (process.env.NODE_ENV !== 'developement') {
// session.cookie['domain'] = process.env.DNS_DOMAIN;
// }

export const baseSession = session as SessionOptions;

0 comments on commit a6e5426

Please sign in to comment.