mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-16 01:32:02 +10:00
- fixes #2153, attempt to fix 401 unauthorized error when implementing OIDC
This commit is contained in:
@ -75,6 +75,7 @@ export class AuthModule {
|
||||
const clientID = configService.getOrThrow("OPENID_CLIENT_ID");
|
||||
const clientSecret = configService.getOrThrow("OPENID_CLIENT_SECRET");
|
||||
const issuer = configService.getOrThrow("OPENID_ISSUER");
|
||||
const scope = configService.getOrThrow("OPENID_SCOPE");
|
||||
const tokenURL = configService.getOrThrow("OPENID_TOKEN_URL");
|
||||
const userInfoURL = configService.getOrThrow("OPENID_USER_INFO_URL");
|
||||
|
||||
@ -84,6 +85,7 @@ export class AuthModule {
|
||||
clientID,
|
||||
clientSecret,
|
||||
issuer,
|
||||
scope,
|
||||
tokenURL,
|
||||
userInfoURL,
|
||||
userService,
|
||||
|
||||
@ -201,12 +201,13 @@ export class AuthService {
|
||||
|
||||
if (
|
||||
this.configService.get("OPENID_AUTHORIZATION_URL") &&
|
||||
this.configService.get("OPENID_ISSUER") &&
|
||||
this.configService.get("OPENID_TOKEN_URL") &&
|
||||
this.configService.get("OPENID_USER_INFO_URL") &&
|
||||
this.configService.get("OPENID_CALLBACK_URL") &&
|
||||
this.configService.get("OPENID_CLIENT_ID") &&
|
||||
this.configService.get("OPENID_CLIENT_SECRET") &&
|
||||
this.configService.get("OPENID_CALLBACK_URL")
|
||||
this.configService.get("OPENID_ISSUER") &&
|
||||
this.configService.get("OPENID_SCOPE") &&
|
||||
this.configService.get("OPENID_TOKEN_URL") &&
|
||||
this.configService.get("OPENID_USER_INFO_URL")
|
||||
) {
|
||||
providers.push("openid");
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { BadRequestException, Injectable } from "@nestjs/common";
|
||||
import { BadRequestException, Injectable, Logger } from "@nestjs/common";
|
||||
import { PassportStrategy } from "@nestjs/passport";
|
||||
import { createId } from "@paralleldrive/cuid2";
|
||||
import { User } from "@prisma/client";
|
||||
import { ErrorMessage, processUsername } from "@reactive-resume/utils";
|
||||
import { Profile, Strategy, StrategyOptions } from "passport-github2";
|
||||
@ -46,15 +47,17 @@ export class GitHubStrategy extends PassportStrategy(Strategy, "github") {
|
||||
email,
|
||||
picture,
|
||||
locale: "en-US",
|
||||
name: displayName,
|
||||
provider: "github",
|
||||
name: displayName || createId(),
|
||||
emailVerified: true, // auto-verify emails
|
||||
username: processUsername(username ?? email.split("@")[0]),
|
||||
secrets: { create: {} },
|
||||
});
|
||||
|
||||
done(null, user);
|
||||
} catch {
|
||||
} catch (error) {
|
||||
Logger.error(error);
|
||||
|
||||
throw new BadRequestException(ErrorMessage.UserAlreadyExists);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { BadRequestException, Injectable } from "@nestjs/common";
|
||||
import { BadRequestException, Injectable, Logger } from "@nestjs/common";
|
||||
import { PassportStrategy } from "@nestjs/passport";
|
||||
import { createId } from "@paralleldrive/cuid2";
|
||||
import { User } from "@prisma/client";
|
||||
import { ErrorMessage, processUsername } from "@reactive-resume/utils";
|
||||
import { Profile, Strategy, StrategyOptions, VerifyCallback } from "passport-google-oauth20";
|
||||
@ -46,15 +47,17 @@ export class GoogleStrategy extends PassportStrategy(Strategy, "google") {
|
||||
email,
|
||||
picture,
|
||||
locale: "en-US",
|
||||
name: displayName,
|
||||
provider: "google",
|
||||
name: displayName || createId(),
|
||||
emailVerified: true, // auto-verify emails
|
||||
username: processUsername(username ?? email.split("@")[0]),
|
||||
secrets: { create: {} },
|
||||
});
|
||||
|
||||
done(null, user);
|
||||
} catch {
|
||||
} catch (error) {
|
||||
Logger.error(error);
|
||||
|
||||
throw new BadRequestException(ErrorMessage.UserAlreadyExists);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { BadRequestException, Injectable } from "@nestjs/common";
|
||||
import { BadRequestException, Injectable, Logger } from "@nestjs/common";
|
||||
import { PassportStrategy } from "@nestjs/passport";
|
||||
import { User } from "@prisma/client";
|
||||
import { ErrorMessage, processUsername } from "@reactive-resume/utils";
|
||||
import { ErrorMessage, generateRandomName, processUsername } from "@reactive-resume/utils";
|
||||
import { Profile, Strategy, StrategyOptions } from "passport-openidconnect";
|
||||
|
||||
import { UserService } from "@/server/user/user.service";
|
||||
@ -14,6 +14,7 @@ export class OpenIDStrategy extends PassportStrategy(Strategy, "openid") {
|
||||
readonly clientID: string,
|
||||
readonly clientSecret: string,
|
||||
readonly issuer: string,
|
||||
readonly scope: string,
|
||||
readonly tokenURL: string,
|
||||
readonly userInfoURL: string,
|
||||
private readonly userService: UserService,
|
||||
@ -24,20 +25,21 @@ export class OpenIDStrategy extends PassportStrategy(Strategy, "openid") {
|
||||
clientID,
|
||||
clientSecret,
|
||||
issuer,
|
||||
scope,
|
||||
tokenURL,
|
||||
userInfoURL,
|
||||
scope: "openid email profile",
|
||||
} as StrategyOptions);
|
||||
}
|
||||
|
||||
async validate(
|
||||
issuer: unknown,
|
||||
_issuer: unknown,
|
||||
profile: Profile,
|
||||
done: (err?: string | Error | null, user?: Express.User, info?: unknown) => void,
|
||||
) {
|
||||
const { displayName, emails, photos, username } = profile;
|
||||
|
||||
const email = emails?.[0].value ?? `${username}@openid.com`;
|
||||
const uniqueId = generateRandomName({ length: 2, style: "lowerCase", separator: "-" });
|
||||
const email = emails?.[0].value ?? `${username ?? uniqueId}@openid.com`;
|
||||
const picture = photos?.[0].value;
|
||||
|
||||
let user: User | null = null;
|
||||
@ -58,15 +60,17 @@ export class OpenIDStrategy extends PassportStrategy(Strategy, "openid") {
|
||||
email,
|
||||
picture,
|
||||
locale: "en-US",
|
||||
name: displayName,
|
||||
provider: "openid",
|
||||
name: displayName || uniqueId,
|
||||
emailVerified: true, // auto-verify emails
|
||||
username: processUsername(username ?? email.split("@")[0]),
|
||||
secrets: { create: {} },
|
||||
});
|
||||
|
||||
done(null, user);
|
||||
} catch {
|
||||
} catch (error) {
|
||||
Logger.error(error);
|
||||
|
||||
throw new BadRequestException(ErrorMessage.UserAlreadyExists);
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,11 +74,13 @@ export const configSchema = z.object({
|
||||
GOOGLE_CALLBACK_URL: z.string().url().optional(),
|
||||
|
||||
// OpenID (Optional)
|
||||
VITE_OPENID_NAME: z.string().optional(),
|
||||
OPENID_AUTHORIZATION_URL: z.string().url().optional(),
|
||||
OPENID_CALLBACK_URL: z.string().url().optional(),
|
||||
OPENID_CLIENT_ID: z.string().optional(),
|
||||
OPENID_CLIENT_SECRET: z.string().optional(),
|
||||
OPENID_ISSUER: z.string().optional(),
|
||||
OPENID_SCOPE: z.string().optional(),
|
||||
OPENID_TOKEN_URL: z.string().url().optional(),
|
||||
OPENID_USER_INFO_URL: z.string().url().optional(),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user