Skip to content

Commit

Permalink
lint and fix api.planx.uk
Browse files Browse the repository at this point in the history
  • Loading branch information
freemvmt committed Jul 18, 2024
1 parent 925e2c3 commit 0ad864f
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 36 deletions.
2 changes: 1 addition & 1 deletion api.planx.uk/modules/auth/controller.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CookieOptions, RequestHandler, Response } from "express";
import { Request } from "express-jwt";

import { microsoftOidcClient } from './passport'
import { microsoftOidcClient } from "./passport";

Check warning on line 4 in api.planx.uk/modules/auth/controller.ts

View workflow job for this annotation

GitHub Actions / Run API Tests

'microsoftOidcClient' is defined but never used. Allowed unused vars must match /^_/u

export const failedLogin: RequestHandler = (_req, _res, next) =>
next({
Expand Down
6 changes: 3 additions & 3 deletions api.planx.uk/modules/auth/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { expressjwt } from "express-jwt";
import { RequestHandler } from "http-proxy-middleware";
import { AsyncLocalStorage } from "async_hooks";
import { Request } from "express";
import { generators } from 'openid-client'
import { generators } from "openid-client";

import { Role } from "@opensystemslab/planx-core/types";

Expand Down Expand Up @@ -130,8 +130,8 @@ export const useMicrosoftAuth: RequestHandler = (req, res, next) => {
// generate a nonce to enable us to validate the response from OP
const nonce = generators.nonce();
console.debug(`Generated a nonce: %s`, nonce);
req.session!.nonce = nonce
req.session!.nonce = nonce;

// @ts-expect-error (method not typed to accept nonce, but it does pass it to the strategy)
return passportWithStrategies.authenticate("microsoft-oidc", {
prompt: "select_account",
Expand Down
35 changes: 21 additions & 14 deletions api.planx.uk/modules/auth/passport.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,47 @@
import { custom, Issuer } from 'openid-client';
import passport from 'passport';
import { custom, Issuer } from "openid-client";
import passport from "passport";

import { googleStrategy } from './strategy/google';
import { getMicrosoftOidcStrategy, getMicrosoftClientConfig, MICROSOFT_OPENID_CONFIG_URL } from './strategy/microsoft-oidc';
import { googleStrategy } from "./strategy/google";
import {
getMicrosoftOidcStrategy,
getMicrosoftClientConfig,
MICROSOFT_OPENID_CONFIG_URL,
} from "./strategy/microsoft-oidc";

const setupPassport = () => {
// TODO: remove below config (timeout extended for local testing with poor connection)
custom.setHttpOptionsDefaults({
timeout: 10000,
})
});

// explicitly instantiate new passport for clarity
let passportWithStrategies = new passport.Passport()
const passportWithStrategies = new passport.Passport();

// build Microsoft OIDC client, and use it to build the related strategy
let microsoftOidcClient;
Issuer.discover(MICROSOFT_OPENID_CONFIG_URL).then(microsoftIssuer => {
Issuer.discover(MICROSOFT_OPENID_CONFIG_URL).then((microsoftIssuer) => {
console.debug("Discovered issuer %s", microsoftIssuer.issuer);
const microsoftClientConfig = getMicrosoftClientConfig();
microsoftOidcClient = new microsoftIssuer.Client(microsoftClientConfig);
console.debug("Built Microsoft client: %O", microsoftOidcClient);
passportWithStrategies.use('microsoft-oidc', getMicrosoftOidcStrategy(microsoftOidcClient));
passportWithStrategies.use(
"microsoft-oidc",
getMicrosoftOidcStrategy(microsoftOidcClient),
);
});

// do any other aspects of passport setup which can be handled here
passportWithStrategies.use('google', googleStrategy);
passportWithStrategies.use("google", googleStrategy);
passportWithStrategies.serializeUser((user: any, done) => {

Check warning on line 35 in api.planx.uk/modules/auth/passport.ts

View workflow job for this annotation

GitHub Actions / Run API Tests

Unexpected any. Specify a different type
done(null, user);
});
passportWithStrategies.deserializeUser((obj: any, done) => {

Check warning on line 38 in api.planx.uk/modules/auth/passport.ts

View workflow job for this annotation

GitHub Actions / Run API Tests

Unexpected any. Specify a different type
done(null, obj);
});
return { passportWithStrategies, microsoftOidcClient }
}

return { passportWithStrategies, microsoftOidcClient };
};

// instantiate and export the new passport class and Microsoft client as early as possible
let { passportWithStrategies, microsoftOidcClient } = setupPassport();
export { passportWithStrategies, microsoftOidcClient };
const { passportWithStrategies, microsoftOidcClient } = setupPassport();
export { passportWithStrategies, microsoftOidcClient };
2 changes: 1 addition & 1 deletion api.planx.uk/modules/auth/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ router.get(
Middleware.useGoogleCallbackAuth,
Controller.handleSuccess,
);
router.get("/auth/microsoft", Middleware.useMicrosoftAuth)
router.get("/auth/microsoft", Middleware.useMicrosoftAuth);
router.post(
"/auth/microsoft/callback",
Middleware.useMicrosoftCallbackAuth,
Expand Down
40 changes: 23 additions & 17 deletions api.planx.uk/modules/auth/strategy/microsoft-oidc.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
import { Strategy, TokenSet, Client, ClientMetadata } from "openid-client";
import { buildJWT } from "../service";

export const MICROSOFT_OPENID_CONFIG_URL = "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration";
export const MICROSOFT_OPENID_CONFIG_URL =
"https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration";

export const getMicrosoftClientConfig = (): ClientMetadata => {
const client_id = process.env.MICROSOFT_CLIENT_ID!;
if (typeof client_id !== 'string') {
throw new Error('No MICROSOFT_CLIENT_ID in the environment');
if (typeof client_id !== "string") {
throw new Error("No MICROSOFT_CLIENT_ID in the environment");
}
return {
client_id,
client_secret: process.env.MICROSOFT_CLIENT_SECRET!,
redirect_uris: [`${process.env.API_URL_EXT}/auth/microsoft/callback`],
post_logout_redirect_uris: [process.env.EDITOR_URL_EXT!],
response_types: ["id_token"],
}
}
};
};

// oidc = OpenID Connect, an auth standard built on top of OAuth 2.0
export const getMicrosoftOidcStrategy = (
client: Client,
): Strategy<Client> => {
return new Strategy({
export const getMicrosoftOidcStrategy = (client: Client): Strategy<Client> => {
return new Strategy(
{
client: client,
params: {
scope: "openid email profile",
Expand All @@ -41,20 +41,26 @@ export const getMicrosoftOidcStrategy = (
const login_hint = claims.login_hint;

Check warning on line 41 in api.planx.uk/modules/auth/strategy/microsoft-oidc.ts

View workflow job for this annotation

GitHub Actions / Run API Tests

'login_hint' is assigned a value but never used. Allowed unused vars must match /^_/u

if (returned_nonce != req.session.nonce) {
return done(new Error("Returned nonce does not match session nonce"), null)
};
return done(
new Error("Returned nonce does not match session nonce"),
null,
);
}

if (!email) {
return done (new Error("Unable to authenticate without email"), null)
};
return done(new Error("Unable to authenticate without email"), null);
}

const jwt = await buildJWT(email);

if (!jwt) {
return done({
status: 404,
message: `User (${email}) not found. Do you need to log in to a different Microsoft Account?`,
} as any, null);
return done(
{
status: 404,
message: `User (${email}) not found. Do you need to log in to a different Microsoft Account?`,
} as any,
null,
);
}

return done(null, { jwt });
Expand Down

0 comments on commit 0ad864f

Please sign in to comment.