Skip to content

Instantly share code, notes, and snippets.

@gkobilansky
Created April 24, 2024 05:04
Show Gist options
  • Save gkobilansky/9cc38fa28437dbdd6526f504a73495ee to your computer and use it in GitHub Desktop.
Save gkobilansky/9cc38fa28437dbdd6526f504a73495ee to your computer and use it in GitHub Desktop.
auth.guard.ts
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Error as STError } from 'supertokens-node';
import { verifySession } from 'supertokens-node/recipe/session/framework/express';
import { VerifySessionOptions } from 'supertokens-node/recipe/session';
import * as JsonWebToken from 'jsonwebtoken';
import * as jwks from 'jwks-rsa';
import * as Sentry from '@sentry/node';
@Injectable()
export class AuthGuard implements CanActivate {
client: jwks.JwksClient;
constructor(private readonly verifyOptions?: VerifySessionOptions) {
if (!this.verifyOptions) {
this.verifyOptions = {};
}
this.client = jwks({jwksUri: 'http://localhost:3000/api/auth/jwt/jwks.json'});
}
async canActivate(context: ExecutionContext): Promise<boolean> {
const ctx = context.switchToHttp();
let err = undefined;
this.verifyOptions.sessionRequired = true;
const req = ctx.getRequest();
const resp = ctx.getResponse();
Sentry.captureMessage('ST Session Creation - w extra', {
level: Sentry.Severity.Debug,
extra: {
url: req.url,
method: req.method,
headers: req.headers,
},
});
// Allow annonymous product purchase
if (req.url.includes('/buy')) {
this.verifyOptions.sessionRequired = false;
}
await verifySession(this.verifyOptions)(req, resp, (res) => {
err = res;
});
if (req.session) {
req.user = {
id: parseInt(req.session.getUserId(), 10),
role: req.session.getAccessTokenPayload().role,
};
}
if (req.headers['authorization']) {
let jwt = req.headers["authorization"];
jwt = jwt === undefined ? undefined : jwt.split('Bearer ')[1];
if (jwt === undefined) {
throw new STError({
message: 'RESPONSE_SENT',
type: 'RESPONSE_SENT',
});
} else {
const kid = '831637a1-40ec-4f64-9813-188648c7744d';
const key = await new Promise<jwks.SigningKey>((resolve, reject) => {
this.client.getSigningKey(kid, (err, key) => {
if (err) {
console.error('err', err);
reject(err);
} else {
console.log('key', key);
resolve(key);
}
});
});
const signingKey = key.getPublicKey();
new Promise((resolve, reject) => {
JsonWebToken.verify(jwt, signingKey, (err, decoded) => {
if (err) {
console.error('err', err);
reject(err);
} else {
let decodedJWT = decoded;
console.log('decodedJWT', decodedJWT);
resolve(decodedJWT);
}
});
})
.then(decodedJWT => {
// Send response with decoded JWT
console.log('decodedJWT', decodedJWT);
return;
})
.catch(err => {
// Handle error
console.error('post promise err', err);
});
}
}
if (resp.headersSent) {
throw new STError({
message: 'RESPONSE_SENT',
type: 'RESPONSE_SENT',
});
}
if (err) {
throw err;
}
console.log('we got to the end of authguard');
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment