- fixes #2153, attempt to fix 401 unauthorized error when implementing OIDC

This commit is contained in:
Amruth Pillai
2025-01-15 16:32:43 +01:00
parent 9a34e4af27
commit 63db927924
16 changed files with 219 additions and 196 deletions

View File

@ -70,10 +70,12 @@ STORAGE_SKIP_BUCKET_CHECK=false
# GOOGLE_CALLBACK_URL=http://localhost:5173/api/auth/google/callback
# OpenID (Optional)
# VITE_OPENID_NAME=
# OPENID_AUTHORIZATION_URL=
# OPENID_CALLBACK_URL=http://localhost:5173/api/auth/openid/callback
# OPENID_CLIENT_ID=
# OPENID_CLIENT_SECRET=
# OPENID_ISSUER=
# OPENID_SCOPE=openid profile email
# OPENID_TOKEN_URL=
# OPENID_USER_INFO_URL=

View File

@ -41,7 +41,7 @@ export const SocialAuth = () => {
>
<a href="/api/auth/openid">
<Fingerprint className="mr-3 size-4" />
{t`OpenID`}
{import.meta.env.VITE_OPENID_NAME}
</a>
</Button>
)}

View File

@ -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,

View File

@ -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");
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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(),
});

View File

@ -1,3 +1,4 @@
import type { Config as UniqueNamesConfig } from "unique-names-generator";
import { adjectives, animals, uniqueNamesGenerator } from "unique-names-generator";
import type { LayoutLocator, SortablePayload } from "./types";
@ -30,12 +31,13 @@ export const extractUrl = (string: string) => {
return result ? result[0] : null;
};
export const generateRandomName = () => {
export const generateRandomName = (options?: Omit<UniqueNamesConfig, "dictionaries">) => {
return uniqueNamesGenerator({
dictionaries: [adjectives, adjectives, animals],
style: "capital",
separator: " ",
length: 3,
...options,
});
};

View File

@ -1,7 +1,7 @@
{
"name": "@reactive-resume/source",
"description": "A free and open-source resume builder that simplifies the process of creating, updating, and sharing your resume.",
"version": "4.3.8",
"version": "4.3.9",
"license": "MIT",
"private": true,
"author": {
@ -96,7 +96,7 @@
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-lingui": "^0.9.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-prettier": "^5.2.2",
"eslint-plugin-react": "^7.37.4",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-simple-import-sort": "^12.1.1",
@ -107,7 +107,7 @@
"jest-environment-node": "^29.7.0",
"jsdom": "^25.0.1",
"nx": "^19.8.14",
"postcss": "^8.5.0",
"postcss": "^8.5.1",
"postcss-import": "^16.1.0",
"postcss-nested": "^6.2.0",
"prettier": "^3.4.2",
@ -195,7 +195,7 @@
"deepmerge": "^4.3.1",
"express-session": "^1.18.1",
"file-saver": "^2.0.5",
"framer-motion": "^11.17.1",
"framer-motion": "^11.18.0",
"fuzzy": "^0.1.3",
"helmet": "^7.2.0",
"immer": "^10.1.1",

340
pnpm-lock.yaml generated
View File

@ -228,8 +228,8 @@ importers:
specifier: ^2.0.5
version: 2.0.5
framer-motion:
specifier: ^11.17.1
version: 11.17.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
specifier: ^11.18.0
version: 11.18.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
fuzzy:
specifier: ^0.1.3
version: 0.1.3
@ -563,7 +563,7 @@ importers:
version: 2.1.8(vitest@2.1.8)
autoprefixer:
specifier: ^10.4.20
version: 10.4.20(postcss@8.5.0)
version: 10.4.20(postcss@8.5.1)
babel-plugin-macros:
specifier: ^3.1.0
version: 3.1.0
@ -583,8 +583,8 @@ importers:
specifier: ^0.9.0
version: 0.9.0(eslint@8.57.0)(typescript@5.7.3)
eslint-plugin-prettier:
specifier: ^5.2.1
version: 5.2.1(@types/eslint@8.56.5)(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.4.2)
specifier: ^5.2.2
version: 5.2.2(@types/eslint@8.56.5)(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.4.2)
eslint-plugin-react:
specifier: ^7.37.4
version: 7.37.4(eslint@8.57.0)
@ -616,14 +616,14 @@ importers:
specifier: ^19.8.14
version: 19.8.14(@swc-node/register@1.10.9(@swc/core@1.10.7(@swc/helpers@0.5.15))(@swc/types@0.1.17)(typescript@5.7.3))(@swc/core@1.10.7(@swc/helpers@0.5.15))
postcss:
specifier: ^8.5.0
version: 8.5.0
specifier: ^8.5.1
version: 8.5.1
postcss-import:
specifier: ^16.1.0
version: 16.1.0(postcss@8.5.0)
version: 16.1.0(postcss@8.5.1)
postcss-nested:
specifier: ^6.2.0
version: 6.2.0(postcss@8.5.0)
version: 6.2.0(postcss@8.5.1)
prettier:
specifier: ^3.4.2
version: 3.4.2
@ -6371,8 +6371,8 @@ packages:
peerDependencies:
eslint: ^8.37.0 || ^9.0.0
eslint-plugin-prettier@5.2.1:
resolution: {integrity: sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==}
eslint-plugin-prettier@5.2.2:
resolution: {integrity: sha512-1yI3/hf35wmlq66C8yOyrujQnel+v5l1Vop5Cl2I6ylyNTT1JbuUUnV3/41PzwTzcyDp/oF0jWE3HXvcH5AQOQ==}
engines: {node: ^14.18.0 || >=16.0.0}
peerDependencies:
'@types/eslint': '>=8.0.0'
@ -6785,8 +6785,8 @@ packages:
fraction.js@4.3.7:
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
framer-motion@11.17.1:
resolution: {integrity: sha512-w6hMreGHgLk2M4Wso955zgG6y7xx0sNBs2pKh9RAyoi9cUuhsh3ry8lArbBCs42wpe5zfeC14SI5EdpV/ucOEA==}
framer-motion@11.18.0:
resolution: {integrity: sha512-Vmjl5Al7XqKHzDFnVqzi1H9hzn5w4eN/bdqXTymVpU2UuMQuz9w6UPdsL9dFBeH7loBlnu4qcEXME+nvbkcIOw==}
peerDependencies:
'@emotion/is-prop-valid': '*'
react: ^18.0.0 || ^19.0.0
@ -9356,8 +9356,8 @@ packages:
postcss-value-parser@4.2.0:
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
postcss@8.5.0:
resolution: {integrity: sha512-27VKOqrYfPncKA2NrFOVhP5MGAfHKLYn/Q0mz9cNQyRAKYi3VNHwYU2qKKqPCqgBmeeJ0uAFB56NumXZ5ZReXg==}
postcss@8.5.1:
resolution: {integrity: sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==}
engines: {node: ^10 || ^12 || >=14}
postgres-array@2.0.0:
@ -10287,10 +10287,6 @@ packages:
sorted-array-functions@1.3.0:
resolution: {integrity: sha512-2sqgzeFlid6N4Z2fUQ1cvFmTOLRi/sEDzSQ0OKYchqgoPmQBVyM3959qYx3fpS6Esef80KjmpgPeEr028dP3OA==}
source-map-js@1.2.0:
resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==}
engines: {node: '>=0.10.0'}
source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
@ -14257,7 +14253,7 @@ snapshots:
'@nx/js': 19.8.14(@babel/traverse@7.26.5)(@swc-node/register@1.10.9(@swc/core@1.10.7(@swc/helpers@0.5.15))(@swc/types@0.1.17)(typescript@5.7.3))(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.6)(nx@19.8.14(@swc-node/register@1.10.9(@swc/core@1.10.7(@swc/helpers@0.5.15))(@swc/types@0.1.17)(typescript@5.7.3))(@swc/core@1.10.7(@swc/helpers@0.5.15)))(typescript@5.7.3)
'@phenomnomnominal/tsquery': 5.0.1(typescript@5.7.3)
ajv: 8.13.0
autoprefixer: 10.4.20(postcss@8.5.0)
autoprefixer: 10.4.20(postcss@8.5.1)
babel-loader: 9.1.3(@babel/core@7.26.0)(webpack@5.97.1(@swc/core@1.10.7(@swc/helpers@0.5.15)))
browserslist: 4.24.4
chalk: 4.1.2
@ -14273,9 +14269,9 @@ snapshots:
loader-utils: 2.0.4
mini-css-extract-plugin: 2.4.7(webpack@5.97.1(@swc/core@1.10.7(@swc/helpers@0.5.15)))
parse5: 4.0.0
postcss: 8.5.0
postcss-import: 14.1.0(postcss@8.5.0)
postcss-loader: 6.2.1(postcss@8.5.0)(webpack@5.97.1(@swc/core@1.10.7(@swc/helpers@0.5.15)))
postcss: 8.5.1
postcss-import: 14.1.0(postcss@8.5.1)
postcss-loader: 6.2.1(postcss@8.5.1)(webpack@5.97.1(@swc/core@1.10.7(@swc/helpers@0.5.15)))
rxjs: 7.8.1
sass: 1.71.1
sass-loader: 12.6.0(sass@1.71.1)(webpack@5.97.1(@swc/core@1.10.7(@swc/helpers@0.5.15)))
@ -17031,14 +17027,14 @@ snapshots:
at-least-node@1.0.0: {}
autoprefixer@10.4.20(postcss@8.5.0):
autoprefixer@10.4.20(postcss@8.5.1):
dependencies:
browserslist: 4.23.3
caniuse-lite: 1.0.30001651
fraction.js: 4.3.7
normalize-range: 0.1.2
picocolors: 1.0.1
postcss: 8.5.0
postcss: 8.5.1
postcss-value-parser: 4.2.0
available-typed-arrays@1.0.7:
@ -17853,18 +17849,18 @@ snapshots:
shebang-command: 2.0.0
which: 2.0.2
css-declaration-sorter@7.1.1(postcss@8.5.0):
css-declaration-sorter@7.1.1(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
css-loader@6.10.0(webpack@5.97.1(@swc/core@1.10.7(@swc/helpers@0.5.15))):
dependencies:
icss-utils: 5.1.0(postcss@8.5.0)
postcss: 8.5.0
postcss-modules-extract-imports: 3.0.0(postcss@8.5.0)
postcss-modules-local-by-default: 4.0.4(postcss@8.5.0)
postcss-modules-scope: 3.1.1(postcss@8.5.0)
postcss-modules-values: 4.0.0(postcss@8.5.0)
icss-utils: 5.1.0(postcss@8.5.1)
postcss: 8.5.1
postcss-modules-extract-imports: 3.0.0(postcss@8.5.1)
postcss-modules-local-by-default: 4.0.4(postcss@8.5.1)
postcss-modules-scope: 3.1.1(postcss@8.5.1)
postcss-modules-values: 4.0.0(postcss@8.5.1)
postcss-value-parser: 4.2.0
semver: 7.6.3
optionalDependencies:
@ -17873,9 +17869,9 @@ snapshots:
css-minimizer-webpack-plugin@5.0.1(webpack@5.97.1(@swc/core@1.10.7(@swc/helpers@0.5.15))):
dependencies:
'@jridgewell/trace-mapping': 0.3.25
cssnano: 6.1.0(postcss@8.5.0)
cssnano: 6.1.0(postcss@8.5.1)
jest-worker: 29.7.0
postcss: 8.5.0
postcss: 8.5.1
schema-utils: 4.2.0
serialize-javascript: 6.0.2
webpack: 5.97.1(@swc/core@1.10.7(@swc/helpers@0.5.15))
@ -17902,49 +17898,49 @@ snapshots:
cssesc@3.0.0: {}
cssnano-preset-default@6.1.0(postcss@8.5.0):
cssnano-preset-default@6.1.0(postcss@8.5.1):
dependencies:
browserslist: 4.24.4
css-declaration-sorter: 7.1.1(postcss@8.5.0)
cssnano-utils: 4.0.2(postcss@8.5.0)
postcss: 8.5.0
postcss-calc: 9.0.1(postcss@8.5.0)
postcss-colormin: 6.1.0(postcss@8.5.0)
postcss-convert-values: 6.1.0(postcss@8.5.0)
postcss-discard-comments: 6.0.2(postcss@8.5.0)
postcss-discard-duplicates: 6.0.3(postcss@8.5.0)
postcss-discard-empty: 6.0.3(postcss@8.5.0)
postcss-discard-overridden: 6.0.2(postcss@8.5.0)
postcss-merge-longhand: 6.0.4(postcss@8.5.0)
postcss-merge-rules: 6.1.0(postcss@8.5.0)
postcss-minify-font-values: 6.0.3(postcss@8.5.0)
postcss-minify-gradients: 6.0.3(postcss@8.5.0)
postcss-minify-params: 6.1.0(postcss@8.5.0)
postcss-minify-selectors: 6.0.3(postcss@8.5.0)
postcss-normalize-charset: 6.0.2(postcss@8.5.0)
postcss-normalize-display-values: 6.0.2(postcss@8.5.0)
postcss-normalize-positions: 6.0.2(postcss@8.5.0)
postcss-normalize-repeat-style: 6.0.2(postcss@8.5.0)
postcss-normalize-string: 6.0.2(postcss@8.5.0)
postcss-normalize-timing-functions: 6.0.2(postcss@8.5.0)
postcss-normalize-unicode: 6.1.0(postcss@8.5.0)
postcss-normalize-url: 6.0.2(postcss@8.5.0)
postcss-normalize-whitespace: 6.0.2(postcss@8.5.0)
postcss-ordered-values: 6.0.2(postcss@8.5.0)
postcss-reduce-initial: 6.1.0(postcss@8.5.0)
postcss-reduce-transforms: 6.0.2(postcss@8.5.0)
postcss-svgo: 6.0.3(postcss@8.5.0)
postcss-unique-selectors: 6.0.3(postcss@8.5.0)
css-declaration-sorter: 7.1.1(postcss@8.5.1)
cssnano-utils: 4.0.2(postcss@8.5.1)
postcss: 8.5.1
postcss-calc: 9.0.1(postcss@8.5.1)
postcss-colormin: 6.1.0(postcss@8.5.1)
postcss-convert-values: 6.1.0(postcss@8.5.1)
postcss-discard-comments: 6.0.2(postcss@8.5.1)
postcss-discard-duplicates: 6.0.3(postcss@8.5.1)
postcss-discard-empty: 6.0.3(postcss@8.5.1)
postcss-discard-overridden: 6.0.2(postcss@8.5.1)
postcss-merge-longhand: 6.0.4(postcss@8.5.1)
postcss-merge-rules: 6.1.0(postcss@8.5.1)
postcss-minify-font-values: 6.0.3(postcss@8.5.1)
postcss-minify-gradients: 6.0.3(postcss@8.5.1)
postcss-minify-params: 6.1.0(postcss@8.5.1)
postcss-minify-selectors: 6.0.3(postcss@8.5.1)
postcss-normalize-charset: 6.0.2(postcss@8.5.1)
postcss-normalize-display-values: 6.0.2(postcss@8.5.1)
postcss-normalize-positions: 6.0.2(postcss@8.5.1)
postcss-normalize-repeat-style: 6.0.2(postcss@8.5.1)
postcss-normalize-string: 6.0.2(postcss@8.5.1)
postcss-normalize-timing-functions: 6.0.2(postcss@8.5.1)
postcss-normalize-unicode: 6.1.0(postcss@8.5.1)
postcss-normalize-url: 6.0.2(postcss@8.5.1)
postcss-normalize-whitespace: 6.0.2(postcss@8.5.1)
postcss-ordered-values: 6.0.2(postcss@8.5.1)
postcss-reduce-initial: 6.1.0(postcss@8.5.1)
postcss-reduce-transforms: 6.0.2(postcss@8.5.1)
postcss-svgo: 6.0.3(postcss@8.5.1)
postcss-unique-selectors: 6.0.3(postcss@8.5.1)
cssnano-utils@4.0.2(postcss@8.5.0):
cssnano-utils@4.0.2(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
cssnano@6.1.0(postcss@8.5.0):
cssnano@6.1.0(postcss@8.5.1):
dependencies:
cssnano-preset-default: 6.1.0(postcss@8.5.0)
cssnano-preset-default: 6.1.0(postcss@8.5.1)
lilconfig: 3.1.1
postcss: 8.5.0
postcss: 8.5.1
csso@5.0.5:
dependencies:
@ -18614,7 +18610,7 @@ snapshots:
- supports-color
- typescript
eslint-plugin-prettier@5.2.1(@types/eslint@8.56.5)(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.4.2):
eslint-plugin-prettier@5.2.2(@types/eslint@8.56.5)(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.4.2):
dependencies:
eslint: 8.57.0
prettier: 3.4.2
@ -18657,7 +18653,7 @@ snapshots:
eslint-plugin-tailwindcss@3.17.5(tailwindcss@3.4.17(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.6)(typescript@5.7.3))):
dependencies:
fast-glob: 3.3.2
postcss: 8.5.0
postcss: 8.5.1
tailwindcss: 3.4.17(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.6)(typescript@5.7.3))
eslint-plugin-unicorn@55.0.0(eslint@8.57.0):
@ -19190,7 +19186,7 @@ snapshots:
fraction.js@4.3.7: {}
framer-motion@11.17.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
framer-motion@11.18.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
motion-dom: 11.16.4
motion-utils: 11.16.0
@ -19700,9 +19696,9 @@ snapshots:
dependencies:
safer-buffer: 2.1.2
icss-utils@5.1.0(postcss@8.5.0):
icss-utils@5.1.0(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
identity-obj-proxy@3.0.0:
dependencies:
@ -20925,7 +20921,7 @@ snapshots:
dependencies:
'@babel/parser': 7.26.5
'@babel/types': 7.26.5
source-map-js: 1.2.0
source-map-js: 1.2.1
mailparser@3.6.9:
dependencies:
@ -22174,208 +22170,208 @@ snapshots:
possible-typed-array-names@1.0.0: {}
postcss-calc@9.0.1(postcss@8.5.0):
postcss-calc@9.0.1(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-selector-parser: 6.1.2
postcss-value-parser: 4.2.0
postcss-colormin@6.1.0(postcss@8.5.0):
postcss-colormin@6.1.0(postcss@8.5.1):
dependencies:
browserslist: 4.24.4
caniuse-api: 3.0.0
colord: 2.9.3
postcss: 8.5.0
postcss: 8.5.1
postcss-value-parser: 4.2.0
postcss-convert-values@6.1.0(postcss@8.5.0):
postcss-convert-values@6.1.0(postcss@8.5.1):
dependencies:
browserslist: 4.24.4
postcss: 8.5.0
postcss: 8.5.1
postcss-value-parser: 4.2.0
postcss-discard-comments@6.0.2(postcss@8.5.0):
postcss-discard-comments@6.0.2(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-discard-duplicates@6.0.3(postcss@8.5.0):
postcss-discard-duplicates@6.0.3(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-discard-empty@6.0.3(postcss@8.5.0):
postcss-discard-empty@6.0.3(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-discard-overridden@6.0.2(postcss@8.5.0):
postcss-discard-overridden@6.0.2(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-import@14.1.0(postcss@8.5.0):
postcss-import@14.1.0(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-value-parser: 4.2.0
read-cache: 1.0.0
resolve: 1.22.10
postcss-import@15.1.0(postcss@8.5.0):
postcss-import@15.1.0(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-value-parser: 4.2.0
read-cache: 1.0.0
resolve: 1.22.10
postcss-import@16.1.0(postcss@8.5.0):
postcss-import@16.1.0(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-value-parser: 4.2.0
read-cache: 1.0.0
resolve: 1.22.8
postcss-js@4.0.1(postcss@8.5.0):
postcss-js@4.0.1(postcss@8.5.1):
dependencies:
camelcase-css: 2.0.1
postcss: 8.5.0
postcss: 8.5.1
postcss-load-config@4.0.2(postcss@8.5.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.6)(typescript@5.7.3)):
postcss-load-config@4.0.2(postcss@8.5.1)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.6)(typescript@5.7.3)):
dependencies:
lilconfig: 3.1.3
yaml: 2.4.1
optionalDependencies:
postcss: 8.5.0
postcss: 8.5.1
ts-node: 10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.6)(typescript@5.7.3)
postcss-loader@6.2.1(postcss@8.5.0)(webpack@5.97.1(@swc/core@1.10.7(@swc/helpers@0.5.15))):
postcss-loader@6.2.1(postcss@8.5.1)(webpack@5.97.1(@swc/core@1.10.7(@swc/helpers@0.5.15))):
dependencies:
cosmiconfig: 7.1.0
klona: 2.0.6
postcss: 8.5.0
postcss: 8.5.1
semver: 7.6.3
webpack: 5.97.1(@swc/core@1.10.7(@swc/helpers@0.5.15))
postcss-merge-longhand@6.0.4(postcss@8.5.0):
postcss-merge-longhand@6.0.4(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-value-parser: 4.2.0
stylehacks: 6.1.0(postcss@8.5.0)
stylehacks: 6.1.0(postcss@8.5.1)
postcss-merge-rules@6.1.0(postcss@8.5.0):
postcss-merge-rules@6.1.0(postcss@8.5.1):
dependencies:
browserslist: 4.24.4
caniuse-api: 3.0.0
cssnano-utils: 4.0.2(postcss@8.5.0)
postcss: 8.5.0
cssnano-utils: 4.0.2(postcss@8.5.1)
postcss: 8.5.1
postcss-selector-parser: 6.1.2
postcss-minify-font-values@6.0.3(postcss@8.5.0):
postcss-minify-font-values@6.0.3(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-value-parser: 4.2.0
postcss-minify-gradients@6.0.3(postcss@8.5.0):
postcss-minify-gradients@6.0.3(postcss@8.5.1):
dependencies:
colord: 2.9.3
cssnano-utils: 4.0.2(postcss@8.5.0)
postcss: 8.5.0
cssnano-utils: 4.0.2(postcss@8.5.1)
postcss: 8.5.1
postcss-value-parser: 4.2.0
postcss-minify-params@6.1.0(postcss@8.5.0):
postcss-minify-params@6.1.0(postcss@8.5.1):
dependencies:
browserslist: 4.24.4
cssnano-utils: 4.0.2(postcss@8.5.0)
postcss: 8.5.0
cssnano-utils: 4.0.2(postcss@8.5.1)
postcss: 8.5.1
postcss-value-parser: 4.2.0
postcss-minify-selectors@6.0.3(postcss@8.5.0):
postcss-minify-selectors@6.0.3(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-selector-parser: 6.1.2
postcss-modules-extract-imports@3.0.0(postcss@8.5.0):
postcss-modules-extract-imports@3.0.0(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-modules-local-by-default@4.0.4(postcss@8.5.0):
postcss-modules-local-by-default@4.0.4(postcss@8.5.1):
dependencies:
icss-utils: 5.1.0(postcss@8.5.0)
postcss: 8.5.0
icss-utils: 5.1.0(postcss@8.5.1)
postcss: 8.5.1
postcss-selector-parser: 6.1.2
postcss-value-parser: 4.2.0
postcss-modules-scope@3.1.1(postcss@8.5.0):
postcss-modules-scope@3.1.1(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-selector-parser: 6.1.2
postcss-modules-values@4.0.0(postcss@8.5.0):
postcss-modules-values@4.0.0(postcss@8.5.1):
dependencies:
icss-utils: 5.1.0(postcss@8.5.0)
postcss: 8.5.0
icss-utils: 5.1.0(postcss@8.5.1)
postcss: 8.5.1
postcss-nested@6.2.0(postcss@8.5.0):
postcss-nested@6.2.0(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-selector-parser: 6.1.2
postcss-normalize-charset@6.0.2(postcss@8.5.0):
postcss-normalize-charset@6.0.2(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-normalize-display-values@6.0.2(postcss@8.5.0):
postcss-normalize-display-values@6.0.2(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-value-parser: 4.2.0
postcss-normalize-positions@6.0.2(postcss@8.5.0):
postcss-normalize-positions@6.0.2(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-value-parser: 4.2.0
postcss-normalize-repeat-style@6.0.2(postcss@8.5.0):
postcss-normalize-repeat-style@6.0.2(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-value-parser: 4.2.0
postcss-normalize-string@6.0.2(postcss@8.5.0):
postcss-normalize-string@6.0.2(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-value-parser: 4.2.0
postcss-normalize-timing-functions@6.0.2(postcss@8.5.0):
postcss-normalize-timing-functions@6.0.2(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-value-parser: 4.2.0
postcss-normalize-unicode@6.1.0(postcss@8.5.0):
postcss-normalize-unicode@6.1.0(postcss@8.5.1):
dependencies:
browserslist: 4.24.4
postcss: 8.5.0
postcss: 8.5.1
postcss-value-parser: 4.2.0
postcss-normalize-url@6.0.2(postcss@8.5.0):
postcss-normalize-url@6.0.2(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-value-parser: 4.2.0
postcss-normalize-whitespace@6.0.2(postcss@8.5.0):
postcss-normalize-whitespace@6.0.2(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-value-parser: 4.2.0
postcss-ordered-values@6.0.2(postcss@8.5.0):
postcss-ordered-values@6.0.2(postcss@8.5.1):
dependencies:
cssnano-utils: 4.0.2(postcss@8.5.0)
postcss: 8.5.0
cssnano-utils: 4.0.2(postcss@8.5.1)
postcss: 8.5.1
postcss-value-parser: 4.2.0
postcss-reduce-initial@6.1.0(postcss@8.5.0):
postcss-reduce-initial@6.1.0(postcss@8.5.1):
dependencies:
browserslist: 4.24.4
caniuse-api: 3.0.0
postcss: 8.5.0
postcss: 8.5.1
postcss-reduce-transforms@6.0.2(postcss@8.5.0):
postcss-reduce-transforms@6.0.2(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-value-parser: 4.2.0
postcss-selector-parser@6.0.10:
@ -22388,20 +22384,20 @@ snapshots:
cssesc: 3.0.0
util-deprecate: 1.0.2
postcss-svgo@6.0.3(postcss@8.5.0):
postcss-svgo@6.0.3(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-value-parser: 4.2.0
svgo: 3.2.0
postcss-unique-selectors@6.0.3(postcss@8.5.0):
postcss-unique-selectors@6.0.3(postcss@8.5.1):
dependencies:
postcss: 8.5.0
postcss: 8.5.1
postcss-selector-parser: 6.1.2
postcss-value-parser@4.2.0: {}
postcss@8.5.0:
postcss@8.5.1:
dependencies:
nanoid: 3.3.8
picocolors: 1.1.1
@ -23184,7 +23180,7 @@ snapshots:
dependencies:
chokidar: 3.6.0
immutable: 4.3.5
source-map-js: 1.2.0
source-map-js: 1.2.1
sax@1.3.0: {}
@ -23494,14 +23490,12 @@ snapshots:
sorted-array-functions@1.3.0: {}
source-map-js@1.2.0: {}
source-map-js@1.2.1: {}
source-map-loader@5.0.0(webpack@5.97.1(@swc/core@1.10.7(@swc/helpers@0.5.15))):
dependencies:
iconv-lite: 0.6.3
source-map-js: 1.2.0
source-map-js: 1.2.1
webpack: 5.97.1(@swc/core@1.10.7(@swc/helpers@0.5.15))
source-map-support@0.5.13:
@ -23743,10 +23737,10 @@ snapshots:
dependencies:
webpack: 5.97.1(@swc/core@1.10.7(@swc/helpers@0.5.15))
stylehacks@6.1.0(postcss@8.5.0):
stylehacks@6.1.0(postcss@8.5.1):
dependencies:
browserslist: 4.24.4
postcss: 8.5.0
postcss: 8.5.1
postcss-selector-parser: 6.1.2
stylus-loader@7.1.3(stylus@0.64.0)(webpack@5.97.1(@swc/core@1.10.7(@swc/helpers@0.5.15))):
@ -23849,11 +23843,11 @@ snapshots:
normalize-path: 3.0.0
object-hash: 3.0.0
picocolors: 1.1.1
postcss: 8.5.0
postcss-import: 15.1.0(postcss@8.5.0)
postcss-js: 4.0.1(postcss@8.5.0)
postcss-load-config: 4.0.2(postcss@8.5.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.6)(typescript@5.7.3))
postcss-nested: 6.2.0(postcss@8.5.0)
postcss: 8.5.1
postcss-import: 15.1.0(postcss@8.5.1)
postcss-js: 4.0.1(postcss@8.5.1)
postcss-load-config: 4.0.2(postcss@8.5.1)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.6)(typescript@5.7.3))
postcss-nested: 6.2.0(postcss@8.5.1)
postcss-selector-parser: 6.1.2
resolve: 1.22.10
sucrase: 3.35.0
@ -24441,7 +24435,7 @@ snapshots:
vite@5.4.11(@types/node@22.10.6)(less@4.1.3)(sass@1.71.1)(stylus@0.64.0)(terser@5.29.1):
dependencies:
esbuild: 0.21.5
postcss: 8.5.0
postcss: 8.5.1
rollup: 4.30.1
optionalDependencies:
'@types/node': 22.10.6

View File

@ -108,11 +108,13 @@ services:
# GOOGLE_CALLBACK_URL: https://example.com/api/auth/google/callback
# -- OpenID (Optional) --
# VITE_OPENID_NAME: OpenID
# OPENID_AUTHORIZATION_URL:
# OPENID_CALLBACK_URL: https://example.com/api/auth/openid/callback
# OPENID_CLIENT_ID:
# OPENID_CLIENT_SECRET:
# OPENID_ISSUER:
# OPENID_SCOPE: openid profile email
# OPENID_TOKEN_URL:
# OPENID_USER_INFO_URL:

View File

@ -107,11 +107,13 @@ services:
# GOOGLE_CALLBACK_URL: http://localhost:3000/api/auth/google/callback
# -- OpenID (Optional) --
# VITE_OPENID_NAME: OpenID
# OPENID_AUTHORIZATION_URL:
# OPENID_CALLBACK_URL: http://localhost:3000/api/auth/openid/callback
# OPENID_CLIENT_ID:
# OPENID_CLIENT_SECRET:
# OPENID_ISSUER:
# OPENID_SCOPE: openid profile email
# OPENID_TOKEN_URL:
# OPENID_USER_INFO_URL:

View File

@ -127,11 +127,13 @@ services:
# GOOGLE_CALLBACK_URL: https://example.com/api/auth/google/callback
# -- OpenID (Optional) --
# VITE_OPENID_NAME: OpenID
# OPENID_AUTHORIZATION_URL:
# OPENID_CALLBACK_URL: https://example.com/api/auth/openid/callback
# OPENID_CLIENT_ID:
# OPENID_CLIENT_SECRET:
# OPENID_ISSUER:
# OPENID_SCOPE: openid profile email
# OPENID_TOKEN_URL:
# OPENID_USER_INFO_URL:
deploy:

View File

@ -116,11 +116,13 @@ services:
# GOOGLE_CALLBACK_URL: https://example.com/api/auth/google/callback
# -- OpenID (Optional) --
# VITE_OPENID_NAME: OpenID
# OPENID_AUTHORIZATION_URL:
# OPENID_CALLBACK_URL: https://example.com/api/auth/openid/callback
# OPENID_CLIENT_ID:
# OPENID_CLIENT_SECRET:
# OPENID_ISSUER:
# OPENID_SCOPE: openid profile email
# OPENID_TOKEN_URL:
# OPENID_USER_INFO_URL:
labels:

View File

@ -112,11 +112,13 @@ services:
# GOOGLE_CALLBACK_URL: http://example.com/api/auth/google/callback
# -- OpenID (Optional) --
# VITE_OPENID_NAME: OpenID
# OPENID_AUTHORIZATION_URL:
# OPENID_CALLBACK_URL: http://example.com/api/auth/openid/callback
# OPENID_CLIENT_ID:
# OPENID_CLIENT_SECRET:
# OPENID_ISSUER:
# OPENID_SCOPE: openid profile email
# OPENID_TOKEN_URL:
# OPENID_USER_INFO_URL:
labels: