From 42a2cf951a5b4f08643d492272fc5f8545cdf123 Mon Sep 17 00:00:00 2001 From: Siddharth Suresh Date: Mon, 6 Feb 2023 19:11:42 +0530 Subject: [PATCH] Add secure-password as an Optional peerDependency (#4067) Co-authored-by: Brandon Bayer --- .changeset/thick-peas-jog.md | 7 ++++ packages/blitz-auth/package.json | 10 ++++-- packages/blitz-auth/src/server/auth-utils.ts | 35 ------------------- packages/blitz-auth/src/server/index.ts | 1 + ...-utils.test.ts => secure-password.test.ts} | 2 +- .../blitz-auth/src/server/secure-password.ts | 35 +++++++++++++++++++ .../generator/templates/app/package.js.json | 1 + .../generator/templates/app/package.ts.json | 1 + pnpm-lock.yaml | 22 ++++++------ 9 files changed, 65 insertions(+), 49 deletions(-) create mode 100644 .changeset/thick-peas-jog.md rename packages/blitz-auth/src/server/{auth-utils.test.ts => secure-password.test.ts} (95%) create mode 100644 packages/blitz-auth/src/server/secure-password.ts diff --git a/.changeset/thick-peas-jog.md b/.changeset/thick-peas-jog.md new file mode 100644 index 0000000000..2bfd21b411 --- /dev/null +++ b/.changeset/thick-peas-jog.md @@ -0,0 +1,7 @@ +--- +"@blitzjs/auth": major +--- + +BREAKING CHANGE: secure-password is now an `optional peerDependency`, if you are using `SecurePassword` api, you need to now install `secure-password` in your application. + +This helps users who do not use SecurePassword from having native package build issues. diff --git a/packages/blitz-auth/package.json b/packages/blitz-auth/package.json index 62f0ec4669..4a7025f6a0 100644 --- a/packages/blitz-auth/package.json +++ b/packages/blitz-auth/package.json @@ -34,12 +34,17 @@ "nanoid": "3.2.0", "passport": "0.5.2", "path": "0.12.7", - "secure-password": "4.0.0", "supports-color": "8.1.1", "url": "0.11.0" }, "peerDependencies": { - "blitz": "2.0.0-beta.22" + "blitz": "2.0.0-beta.22", + "secure-password": "4.0.0" + }, + "peerDependenciesMeta": { + "secure-password": { + "optional": true + } }, "devDependencies": { "@blitzjs/config": "workspace:2.0.0-beta.22", @@ -53,6 +58,7 @@ "blitz": "2.0.0-beta.22", "react": "18.2.0", "react-dom": "18.2.0", + "secure-password": "4.0.0", "typescript": "^4.8.4", "unbuild": "0.7.6", "watch": "1.0.2" diff --git a/packages/blitz-auth/src/server/auth-utils.ts b/packages/blitz-auth/src/server/auth-utils.ts index 70421a6b03..9a53ac3005 100644 --- a/packages/blitz-auth/src/server/auth-utils.ts +++ b/packages/blitz-auth/src/server/auth-utils.ts @@ -1,43 +1,8 @@ import * as crypto from "crypto" import {nanoid} from "nanoid" -import SecurePasswordLib from "secure-password" -import {AuthenticationError} from "blitz" export const hash256 = (input: string = "") => { return crypto.createHash("sha256").update(input).digest("hex") } export const generateToken = (numberOfCharacters: number = 32) => nanoid(numberOfCharacters) - -const SP = () => new SecurePasswordLib() - -export const SecurePassword = { - ...SecurePasswordLib, - async hash(password: string | null | undefined) { - if (!password) { - throw new AuthenticationError() - } - const hashedBuffer = await SP().hash(Buffer.from(password)) - return hashedBuffer.toString("base64") - }, - async verify(hashedPassword: string | null | undefined, password: string | null | undefined) { - if (!hashedPassword || !password) { - throw new AuthenticationError() - } - try { - const result = await SP().verify(Buffer.from(password), Buffer.from(hashedPassword, "base64")) - // Return result for valid results. - switch (result) { - case SecurePassword.VALID: - case SecurePassword.VALID_NEEDS_REHASH: - return result - default: - // For everything else throw AuthenticationError - throw new AuthenticationError() - } - } catch (error) { - // Could be error like failed to hash password - throw new AuthenticationError() - } - }, -} diff --git a/packages/blitz-auth/src/server/index.ts b/packages/blitz-auth/src/server/index.ts index 622f94f2ef..9ed9e4427b 100644 --- a/packages/blitz-auth/src/server/index.ts +++ b/packages/blitz-auth/src/server/index.ts @@ -2,3 +2,4 @@ export * from "./auth-sessions" export * from "./auth-utils" export * from "./auth-plugin" export * from "./passport-adapter" +export * from "./secure-password" diff --git a/packages/blitz-auth/src/server/auth-utils.test.ts b/packages/blitz-auth/src/server/secure-password.test.ts similarity index 95% rename from packages/blitz-auth/src/server/auth-utils.test.ts rename to packages/blitz-auth/src/server/secure-password.test.ts index d06c9bed41..3cc2ca4e4e 100644 --- a/packages/blitz-auth/src/server/auth-utils.test.ts +++ b/packages/blitz-auth/src/server/secure-password.test.ts @@ -1,5 +1,5 @@ import {expect, describe, it} from "vitest" -import {SecurePassword} from "./auth-utils" +import {SecurePassword} from "./secure-password" describe("SecurePassword", () => { describe("hash", () => { diff --git a/packages/blitz-auth/src/server/secure-password.ts b/packages/blitz-auth/src/server/secure-password.ts new file mode 100644 index 0000000000..eb1e9fd074 --- /dev/null +++ b/packages/blitz-auth/src/server/secure-password.ts @@ -0,0 +1,35 @@ +import SecurePasswordLib from "secure-password" +import {AuthenticationError} from "blitz" + +const SP = () => new SecurePasswordLib() + +export const SecurePassword = { + ...SecurePasswordLib, + async hash(password: string | null | undefined) { + if (!password) { + throw new AuthenticationError() + } + const hashedBuffer = await SP().hash(Buffer.from(password)) + return hashedBuffer.toString("base64") + }, + async verify(hashedPassword: string | null | undefined, password: string | null | undefined) { + if (!hashedPassword || !password) { + throw new AuthenticationError() + } + try { + const result = await SP().verify(Buffer.from(password), Buffer.from(hashedPassword, "base64")) + // Return result for valid results. + switch (result) { + case SecurePassword.VALID: + case SecurePassword.VALID_NEEDS_REHASH: + return result + default: + // For everything else throw AuthenticationError + throw new AuthenticationError() + } + } catch (error) { + // Could be error like failed to hash password + throw new AuthenticationError() + } + }, +} diff --git a/packages/generator/templates/app/package.js.json b/packages/generator/templates/app/package.js.json index c2b7d13ad9..e93d82a01d 100644 --- a/packages/generator/templates/app/package.js.json +++ b/packages/generator/templates/app/package.js.json @@ -31,6 +31,7 @@ "prisma": "4.6.0", "react": "18.2.0", "react-dom": "18.2.0", + "secure-password": "4.0.0", "zod": "3.19.1" }, "devDependencies": { diff --git a/packages/generator/templates/app/package.ts.json b/packages/generator/templates/app/package.ts.json index 67e8733ec9..4189880533 100644 --- a/packages/generator/templates/app/package.ts.json +++ b/packages/generator/templates/app/package.ts.json @@ -31,6 +31,7 @@ "prisma": "4.6.0", "react": "18.2.0", "react-dom": "18.2.0", + "secure-password": "4.0.0", "zod": "3.20.2" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 482eda1385..808aab833b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -547,7 +547,7 @@ importers: "@vitejs/plugin-react": 1.3.0 delay: 5.0.0 eslint: 8.27.0 - eslint-config-next: 13.1.1_rmayb2veg2btbq6mbmnyivgasy + eslint-config-next: 13.1.5_rmayb2veg2btbq6mbmnyivgasy eslint-plugin-testing-library: 5.0.1_rmayb2veg2btbq6mbmnyivgasy jsdom: 19.0.0 typescript: 4.8.4 @@ -973,7 +973,6 @@ importers: nanoid: 3.2.0 passport: 0.5.2 path: 0.12.7 - secure-password: 4.0.0 supports-color: 8.1.1 url: 0.11.0 devDependencies: @@ -988,6 +987,7 @@ importers: blitz: link:../blitz react: 18.2.0 react-dom: 18.2.0_react@18.2.0 + secure-password: 4.0.0 typescript: 4.8.4 unbuild: 0.7.6_supports-color@8.1.1 watch: 1.0.2 @@ -5091,10 +5091,10 @@ packages: dependencies: glob: 7.1.7 - /@next/eslint-plugin-next/13.1.1: + /@next/eslint-plugin-next/13.1.5: resolution: { - integrity: sha512-SBrOFS8PC3nQ5aeZmawJkjKkWjwK9RoxvBSv/86nZp0ubdoVQoko8r8htALd9ufp16NhacCdqhu9bzZLDWtALQ==, + integrity: sha512-3kvLTX35bOWOCKU8KY74Ygczc55Qk/kB2TQy0tH7Rti6hzZ6Aij7WQ8zHdIVjmnlD0n/zXWXrIf5y56RKcLQkQ==, } dependencies: glob: 7.1.7 @@ -10952,10 +10952,10 @@ packages: - supports-color dev: false - /eslint-config-next/13.1.1_rmayb2veg2btbq6mbmnyivgasy: + /eslint-config-next/13.1.5_rmayb2veg2btbq6mbmnyivgasy: resolution: { - integrity: sha512-/5S2XGWlGaiqrRhzpn51ux5JUSLwx8PVK2keLi5xk7QmhfYB8PqE6R6SlVw6hgnf/VexvUXSrlNJ/su00NhtHQ==, + integrity: sha512-7FqkjkvGCQfvYUiPTFRiRYPR1uI6Ew+4f4mVp16lLSWcaChtWoZxQCZHM5n0yxzKKVmuEg1aM4uvDQfSXSjTww==, } peerDependencies: eslint: ^7.23.0 || ^8.0.0 @@ -10964,7 +10964,7 @@ packages: typescript: optional: true dependencies: - "@next/eslint-plugin-next": 13.1.1 + "@next/eslint-plugin-next": 13.1.5 "@rushstack/eslint-patch": 1.1.3 "@typescript-eslint/parser": 5.43.0_rmayb2veg2btbq6mbmnyivgasy eslint: 8.27.0 @@ -15923,7 +15923,7 @@ packages: { integrity: sha512-C40jQ3NzfkP53NsO8kEOFd79p4b9kDXQMwgiY1z8ZwrDZgUyom0AHwGegF4Dm99L+YoYhuaB0ceerUcXmqr1rQ==, } - dev: false + dev: true /nanoid/3.2.0: resolution: @@ -16159,7 +16159,7 @@ packages: integrity: sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==, } hasBin: true - dev: false + dev: true /node-int64/0.4.0: resolution: @@ -18410,7 +18410,7 @@ packages: dependencies: nanoassert: 1.1.0 sodium-native: 3.3.0 - dev: false + dev: true /selderee/0.6.0: resolution: @@ -18843,7 +18843,7 @@ packages: requiresBuild: true dependencies: node-gyp-build: 4.4.0 - dev: false + dev: true /source-map-js/1.0.2: resolution: