mirror of
https://github.com/wasp-lang/wasp.git
synced 2024-11-23 01:54:37 +03:00
Uses Oslo for password hashing (#1782)
Signed-off-by: Mihovil Ilakovac <mihovil@ilakovac.com>
This commit is contained in:
parent
edb3cbd61f
commit
55ede5684b
@ -1,17 +1,16 @@
|
||||
import SecurePassword from 'secure-password'
|
||||
import { Argon2id } from 'oslo/password'
|
||||
|
||||
const SP = new SecurePassword()
|
||||
const argon2id = new Argon2id()
|
||||
|
||||
// PRIVATE API
|
||||
export const hashPassword = async (password: string): Promise<string> => {
|
||||
const hashedPwdBuffer = await SP.hash(Buffer.from(password))
|
||||
return hashedPwdBuffer.toString("base64")
|
||||
return argon2id.hash(password)
|
||||
}
|
||||
|
||||
// PRIVATE API
|
||||
export const verifyPassword = async (hashedPassword: string, password: string): Promise<void> => {
|
||||
const result = await SP.verify(Buffer.from(password), Buffer.from(hashedPassword, "base64"))
|
||||
if (result !== SecurePassword.VALID) {
|
||||
const isValidPassword = await argon2id.verify(hashedPassword, password)
|
||||
if (!isValidPassword) {
|
||||
throw new Error('Invalid password.')
|
||||
}
|
||||
}
|
||||
|
@ -207,7 +207,7 @@
|
||||
"file",
|
||||
"../out/sdk/wasp/package.json"
|
||||
],
|
||||
"8c4e7254985043dbada72ea8caa14dc82e154e5d1d3384677b7986f9ba8ef833"
|
||||
"6691a48b86fa7e4133f01e647534c32c378755b9c4f266853fdcdc61907e711c"
|
||||
],
|
||||
[
|
||||
[
|
||||
|
@ -1 +1 @@
|
||||
{"_waspSdkNpmDeps":{"dependencies":[{"name":"@prisma/client","version":"4.16.2"},{"name":"prisma","version":"4.16.2"},{"name":"@tanstack/react-query","version":"^4.29.0"},{"name":"axios","version":"^1.4.0"},{"name":"express","version":"~4.18.1"},{"name":"jsonwebtoken","version":"^8.5.1"},{"name":"mitt","version":"3.0.0"},{"name":"react","version":"^18.2.0"},{"name":"lodash.merge","version":"^4.6.2"},{"name":"react-router-dom","version":"^5.3.3"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"secure-password","version":"^4.0.0"},{"name":"sodium-native","version":"3.3.0"},{"name":"superjson","version":"^1.12.2"},{"name":"@types/express-serve-static-core","version":"^4.17.13"},{"name":"uuid","version":"^9.0.0"},{"name":"vitest","version":"^1.2.1"},{"name":"@vitest/ui","version":"^1.2.1"},{"name":"jsdom","version":"^21.1.1"},{"name":"@testing-library/react","version":"^14.1.2"},{"name":"@testing-library/jest-dom","version":"^6.3.0"},{"name":"msw","version":"^1.1.0"}],"devDependencies":[{"name":"@tsconfig/node18","version":"latest"}]},"_userNpmDeps":{"userDependencies":[{"name":"react","version":"^18.2.0"},{"name":"wasp","version":"file:.wasp/out/sdk/wasp"}],"userDevDependencies":[{"name":"@types/react","version":"^18.0.37"},{"name":"prisma","version":"4.16.2"},{"name":"typescript","version":"^5.1.0"},{"name":"vite","version":"^4.3.9"}]},"_waspFrameworkNpmDeps":{"npmDepsForWebApp":{"dependencies":[{"name":"@tanstack/react-query","version":"^4.29.0"},{"name":"axios","version":"^1.4.0"},{"name":"mitt","version":"3.0.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"react-router-dom","version":"^5.3.3"},{"name":"superjson","version":"^1.12.2"}],"devDependencies":[{"name":"@tsconfig/vite-react","version":"^2.0.0"},{"name":"@types/react-dom","version":"^18.0.11"},{"name":"@types/react-router-dom","version":"^5.3.3"},{"name":"@vitejs/plugin-react","version":"^4.2.1"},{"name":"dotenv","version":"^16.0.3"}]},"npmDepsForServer":{"dependencies":[{"name":"cookie-parser","version":"~1.4.6"},{"name":"cors","version":"^2.8.5"},{"name":"dotenv","version":"16.0.2"},{"name":"express","version":"~4.18.1"},{"name":"helmet","version":"^6.0.0"},{"name":"jsonwebtoken","version":"^8.5.1"},{"name":"morgan","version":"~1.10.0"},{"name":"rate-limiter-flexible","version":"^2.4.1"},{"name":"superjson","version":"^1.12.2"}],"devDependencies":[{"name":"@tsconfig/node18","version":"latest"},{"name":"@types/cors","version":"^2.8.5"},{"name":"@types/express","version":"^4.17.13"},{"name":"@types/express-serve-static-core","version":"^4.17.13"},{"name":"@types/node","version":"^18.0.0"},{"name":"nodemon","version":"^2.0.19"},{"name":"rollup","version":"^4.9.6"},{"name":"rollup-plugin-esbuild","version":"^6.1.1"},{"name":"standard","version":"^17.0.0"}]}}}
|
||||
{"_waspSdkNpmDeps":{"dependencies":[{"name":"@prisma/client","version":"4.16.2"},{"name":"prisma","version":"4.16.2"},{"name":"@tanstack/react-query","version":"^4.29.0"},{"name":"axios","version":"^1.4.0"},{"name":"express","version":"~4.18.1"},{"name":"jsonwebtoken","version":"^8.5.1"},{"name":"mitt","version":"3.0.0"},{"name":"react","version":"^18.2.0"},{"name":"lodash.merge","version":"^4.6.2"},{"name":"react-router-dom","version":"^5.3.3"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"superjson","version":"^1.12.2"},{"name":"@types/express-serve-static-core","version":"^4.17.13"},{"name":"uuid","version":"^9.0.0"},{"name":"vitest","version":"^1.2.1"},{"name":"@vitest/ui","version":"^1.2.1"},{"name":"jsdom","version":"^21.1.1"},{"name":"@testing-library/react","version":"^14.1.2"},{"name":"@testing-library/jest-dom","version":"^6.3.0"},{"name":"msw","version":"^1.1.0"}],"devDependencies":[{"name":"@tsconfig/node18","version":"latest"}]},"_userNpmDeps":{"userDependencies":[{"name":"react","version":"^18.2.0"},{"name":"wasp","version":"file:.wasp/out/sdk/wasp"}],"userDevDependencies":[{"name":"@types/react","version":"^18.0.37"},{"name":"prisma","version":"4.16.2"},{"name":"typescript","version":"^5.1.0"},{"name":"vite","version":"^4.3.9"}]},"_waspFrameworkNpmDeps":{"npmDepsForWebApp":{"dependencies":[{"name":"@tanstack/react-query","version":"^4.29.0"},{"name":"axios","version":"^1.4.0"},{"name":"mitt","version":"3.0.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"react-router-dom","version":"^5.3.3"},{"name":"superjson","version":"^1.12.2"}],"devDependencies":[{"name":"@tsconfig/vite-react","version":"^2.0.0"},{"name":"@types/react-dom","version":"^18.0.11"},{"name":"@types/react-router-dom","version":"^5.3.3"},{"name":"@vitejs/plugin-react","version":"^4.2.1"},{"name":"dotenv","version":"^16.0.3"}]},"npmDepsForServer":{"dependencies":[{"name":"cookie-parser","version":"~1.4.6"},{"name":"cors","version":"^2.8.5"},{"name":"dotenv","version":"16.0.2"},{"name":"express","version":"~4.18.1"},{"name":"helmet","version":"^6.0.0"},{"name":"jsonwebtoken","version":"^8.5.1"},{"name":"morgan","version":"~1.10.0"},{"name":"rate-limiter-flexible","version":"^2.4.1"},{"name":"superjson","version":"^1.12.2"}],"devDependencies":[{"name":"@tsconfig/node18","version":"latest"},{"name":"@types/cors","version":"^2.8.5"},{"name":"@types/express","version":"^4.17.13"},{"name":"@types/express-serve-static-core","version":"^4.17.13"},{"name":"@types/node","version":"^18.0.0"},{"name":"nodemon","version":"^2.0.19"},{"name":"rollup","version":"^4.9.6"},{"name":"rollup-plugin-esbuild","version":"^6.1.1"},{"name":"standard","version":"^17.0.0"}]}}}
|
@ -17,8 +17,6 @@
|
||||
"react": "^18.2.0",
|
||||
"react-hook-form": "^7.45.4",
|
||||
"react-router-dom": "^5.3.3",
|
||||
"secure-password": "^4.0.0",
|
||||
"sodium-native": "3.3.0",
|
||||
"superjson": "^1.12.2",
|
||||
"uuid": "^9.0.0",
|
||||
"vitest": "^1.2.1"
|
||||
|
@ -207,7 +207,7 @@
|
||||
"file",
|
||||
"../out/sdk/wasp/package.json"
|
||||
],
|
||||
"8c4e7254985043dbada72ea8caa14dc82e154e5d1d3384677b7986f9ba8ef833"
|
||||
"6691a48b86fa7e4133f01e647534c32c378755b9c4f266853fdcdc61907e711c"
|
||||
],
|
||||
[
|
||||
[
|
||||
|
@ -1 +1 @@
|
||||
{"_waspSdkNpmDeps":{"dependencies":[{"name":"@prisma/client","version":"4.16.2"},{"name":"prisma","version":"4.16.2"},{"name":"@tanstack/react-query","version":"^4.29.0"},{"name":"axios","version":"^1.4.0"},{"name":"express","version":"~4.18.1"},{"name":"jsonwebtoken","version":"^8.5.1"},{"name":"mitt","version":"3.0.0"},{"name":"react","version":"^18.2.0"},{"name":"lodash.merge","version":"^4.6.2"},{"name":"react-router-dom","version":"^5.3.3"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"secure-password","version":"^4.0.0"},{"name":"sodium-native","version":"3.3.0"},{"name":"superjson","version":"^1.12.2"},{"name":"@types/express-serve-static-core","version":"^4.17.13"},{"name":"uuid","version":"^9.0.0"},{"name":"vitest","version":"^1.2.1"},{"name":"@vitest/ui","version":"^1.2.1"},{"name":"jsdom","version":"^21.1.1"},{"name":"@testing-library/react","version":"^14.1.2"},{"name":"@testing-library/jest-dom","version":"^6.3.0"},{"name":"msw","version":"^1.1.0"}],"devDependencies":[{"name":"@tsconfig/node18","version":"latest"}]},"_userNpmDeps":{"userDependencies":[{"name":"react","version":"^18.2.0"},{"name":"wasp","version":"file:.wasp/out/sdk/wasp"}],"userDevDependencies":[{"name":"@types/react","version":"^18.0.37"},{"name":"prisma","version":"4.16.2"},{"name":"typescript","version":"^5.1.0"},{"name":"vite","version":"^4.3.9"}]},"_waspFrameworkNpmDeps":{"npmDepsForWebApp":{"dependencies":[{"name":"@tanstack/react-query","version":"^4.29.0"},{"name":"axios","version":"^1.4.0"},{"name":"mitt","version":"3.0.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"react-router-dom","version":"^5.3.3"},{"name":"superjson","version":"^1.12.2"}],"devDependencies":[{"name":"@tsconfig/vite-react","version":"^2.0.0"},{"name":"@types/react-dom","version":"^18.0.11"},{"name":"@types/react-router-dom","version":"^5.3.3"},{"name":"@vitejs/plugin-react","version":"^4.2.1"},{"name":"dotenv","version":"^16.0.3"}]},"npmDepsForServer":{"dependencies":[{"name":"cookie-parser","version":"~1.4.6"},{"name":"cors","version":"^2.8.5"},{"name":"dotenv","version":"16.0.2"},{"name":"express","version":"~4.18.1"},{"name":"helmet","version":"^6.0.0"},{"name":"jsonwebtoken","version":"^8.5.1"},{"name":"morgan","version":"~1.10.0"},{"name":"rate-limiter-flexible","version":"^2.4.1"},{"name":"superjson","version":"^1.12.2"}],"devDependencies":[{"name":"@tsconfig/node18","version":"latest"},{"name":"@types/cors","version":"^2.8.5"},{"name":"@types/express","version":"^4.17.13"},{"name":"@types/express-serve-static-core","version":"^4.17.13"},{"name":"@types/node","version":"^18.0.0"},{"name":"nodemon","version":"^2.0.19"},{"name":"rollup","version":"^4.9.6"},{"name":"rollup-plugin-esbuild","version":"^6.1.1"},{"name":"standard","version":"^17.0.0"}]}}}
|
||||
{"_waspSdkNpmDeps":{"dependencies":[{"name":"@prisma/client","version":"4.16.2"},{"name":"prisma","version":"4.16.2"},{"name":"@tanstack/react-query","version":"^4.29.0"},{"name":"axios","version":"^1.4.0"},{"name":"express","version":"~4.18.1"},{"name":"jsonwebtoken","version":"^8.5.1"},{"name":"mitt","version":"3.0.0"},{"name":"react","version":"^18.2.0"},{"name":"lodash.merge","version":"^4.6.2"},{"name":"react-router-dom","version":"^5.3.3"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"superjson","version":"^1.12.2"},{"name":"@types/express-serve-static-core","version":"^4.17.13"},{"name":"uuid","version":"^9.0.0"},{"name":"vitest","version":"^1.2.1"},{"name":"@vitest/ui","version":"^1.2.1"},{"name":"jsdom","version":"^21.1.1"},{"name":"@testing-library/react","version":"^14.1.2"},{"name":"@testing-library/jest-dom","version":"^6.3.0"},{"name":"msw","version":"^1.1.0"}],"devDependencies":[{"name":"@tsconfig/node18","version":"latest"}]},"_userNpmDeps":{"userDependencies":[{"name":"react","version":"^18.2.0"},{"name":"wasp","version":"file:.wasp/out/sdk/wasp"}],"userDevDependencies":[{"name":"@types/react","version":"^18.0.37"},{"name":"prisma","version":"4.16.2"},{"name":"typescript","version":"^5.1.0"},{"name":"vite","version":"^4.3.9"}]},"_waspFrameworkNpmDeps":{"npmDepsForWebApp":{"dependencies":[{"name":"@tanstack/react-query","version":"^4.29.0"},{"name":"axios","version":"^1.4.0"},{"name":"mitt","version":"3.0.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"react-router-dom","version":"^5.3.3"},{"name":"superjson","version":"^1.12.2"}],"devDependencies":[{"name":"@tsconfig/vite-react","version":"^2.0.0"},{"name":"@types/react-dom","version":"^18.0.11"},{"name":"@types/react-router-dom","version":"^5.3.3"},{"name":"@vitejs/plugin-react","version":"^4.2.1"},{"name":"dotenv","version":"^16.0.3"}]},"npmDepsForServer":{"dependencies":[{"name":"cookie-parser","version":"~1.4.6"},{"name":"cors","version":"^2.8.5"},{"name":"dotenv","version":"16.0.2"},{"name":"express","version":"~4.18.1"},{"name":"helmet","version":"^6.0.0"},{"name":"jsonwebtoken","version":"^8.5.1"},{"name":"morgan","version":"~1.10.0"},{"name":"rate-limiter-flexible","version":"^2.4.1"},{"name":"superjson","version":"^1.12.2"}],"devDependencies":[{"name":"@tsconfig/node18","version":"latest"},{"name":"@types/cors","version":"^2.8.5"},{"name":"@types/express","version":"^4.17.13"},{"name":"@types/express-serve-static-core","version":"^4.17.13"},{"name":"@types/node","version":"^18.0.0"},{"name":"nodemon","version":"^2.0.19"},{"name":"rollup","version":"^4.9.6"},{"name":"rollup-plugin-esbuild","version":"^6.1.1"},{"name":"standard","version":"^17.0.0"}]}}}
|
@ -17,8 +17,6 @@
|
||||
"react": "^18.2.0",
|
||||
"react-hook-form": "^7.45.4",
|
||||
"react-router-dom": "^5.3.3",
|
||||
"secure-password": "^4.0.0",
|
||||
"sodium-native": "3.3.0",
|
||||
"superjson": "^1.12.2",
|
||||
"uuid": "^9.0.0",
|
||||
"vitest": "^1.2.1"
|
||||
|
@ -123,7 +123,7 @@
|
||||
"file",
|
||||
"../out/sdk/wasp/auth/password.ts"
|
||||
],
|
||||
"dfcf3e3fe8772049f3fb90fef0da794a759f990a4fef400ce08f9dbd107efa38"
|
||||
"1be6716ab375f1ac492e2ed65e6343990770397946cadef292e92eaa3b3ceefc"
|
||||
],
|
||||
[
|
||||
[
|
||||
@ -480,7 +480,7 @@
|
||||
"file",
|
||||
"../out/sdk/wasp/package.json"
|
||||
],
|
||||
"5d72459af3a4e005f73ab8d7fa818b1e8e9225dfdf650809e64e620a22af7e43"
|
||||
"b53c678e00bdf4457cbb1f957482203dad88eb527fcd2d81e87d5f49004e78e1"
|
||||
],
|
||||
[
|
||||
[
|
||||
|
@ -1 +1 @@
|
||||
{"_waspSdkNpmDeps":{"dependencies":[{"name":"@prisma/client","version":"4.16.2"},{"name":"prisma","version":"4.16.2"},{"name":"@tanstack/react-query","version":"^4.29.0"},{"name":"axios","version":"^1.4.0"},{"name":"express","version":"~4.18.1"},{"name":"jsonwebtoken","version":"^8.5.1"},{"name":"mitt","version":"3.0.0"},{"name":"react","version":"^18.2.0"},{"name":"lodash.merge","version":"^4.6.2"},{"name":"react-router-dom","version":"^5.3.3"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"secure-password","version":"^4.0.0"},{"name":"sodium-native","version":"3.3.0"},{"name":"superjson","version":"^1.12.2"},{"name":"@types/express-serve-static-core","version":"^4.17.13"},{"name":"@stitches/react","version":"^1.2.8"},{"name":"lucia","version":"^3.0.0-beta.14"},{"name":"@lucia-auth/adapter-prisma","version":"^4.0.0-beta.9"},{"name":"@sendgrid/mail","version":"^7.7.0"},{"name":"uuid","version":"^9.0.0"},{"name":"vitest","version":"^1.2.1"},{"name":"@vitest/ui","version":"^1.2.1"},{"name":"jsdom","version":"^21.1.1"},{"name":"@testing-library/react","version":"^14.1.2"},{"name":"@testing-library/jest-dom","version":"^6.3.0"},{"name":"msw","version":"^1.1.0"},{"name":"pg-boss","version":"^8.4.2"}],"devDependencies":[{"name":"@tsconfig/node18","version":"latest"}]},"_userNpmDeps":{"userDependencies":[{"name":"react","version":"^18.2.0"},{"name":"wasp","version":"file:.wasp/out/sdk/wasp"}],"userDevDependencies":[{"name":"@types/react","version":"^18.0.37"},{"name":"prisma","version":"4.16.2"},{"name":"typescript","version":"^5.1.0"},{"name":"vite","version":"^4.3.9"}]},"_waspFrameworkNpmDeps":{"npmDepsForWebApp":{"dependencies":[{"name":"@tanstack/react-query","version":"^4.29.0"},{"name":"axios","version":"^1.4.0"},{"name":"mitt","version":"3.0.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"react-router-dom","version":"^5.3.3"},{"name":"superjson","version":"^1.12.2"}],"devDependencies":[{"name":"@tsconfig/vite-react","version":"^2.0.0"},{"name":"@types/react-dom","version":"^18.0.11"},{"name":"@types/react-router-dom","version":"^5.3.3"},{"name":"@vitejs/plugin-react","version":"^4.2.1"},{"name":"dotenv","version":"^16.0.3"}]},"npmDepsForServer":{"dependencies":[{"name":"cookie-parser","version":"~1.4.6"},{"name":"cors","version":"^2.8.5"},{"name":"dotenv","version":"16.0.2"},{"name":"express","version":"~4.18.1"},{"name":"helmet","version":"^6.0.0"},{"name":"jsonwebtoken","version":"^8.5.1"},{"name":"morgan","version":"~1.10.0"},{"name":"passport","version":"0.6.0"},{"name":"passport-google-oauth20","version":"2.0.0"},{"name":"rate-limiter-flexible","version":"^2.4.1"},{"name":"superjson","version":"^1.12.2"}],"devDependencies":[{"name":"@tsconfig/node18","version":"latest"},{"name":"@types/cors","version":"^2.8.5"},{"name":"@types/express","version":"^4.17.13"},{"name":"@types/express-serve-static-core","version":"^4.17.13"},{"name":"@types/node","version":"^18.0.0"},{"name":"nodemon","version":"^2.0.19"},{"name":"rollup","version":"^4.9.6"},{"name":"rollup-plugin-esbuild","version":"^6.1.1"},{"name":"standard","version":"^17.0.0"}]}}}
|
||||
{"_waspSdkNpmDeps":{"dependencies":[{"name":"@prisma/client","version":"4.16.2"},{"name":"prisma","version":"4.16.2"},{"name":"@tanstack/react-query","version":"^4.29.0"},{"name":"axios","version":"^1.4.0"},{"name":"express","version":"~4.18.1"},{"name":"jsonwebtoken","version":"^8.5.1"},{"name":"mitt","version":"3.0.0"},{"name":"react","version":"^18.2.0"},{"name":"lodash.merge","version":"^4.6.2"},{"name":"react-router-dom","version":"^5.3.3"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"superjson","version":"^1.12.2"},{"name":"@types/express-serve-static-core","version":"^4.17.13"},{"name":"@stitches/react","version":"^1.2.8"},{"name":"lucia","version":"^3.0.1"},{"name":"@lucia-auth/adapter-prisma","version":"^4.0.0"},{"name":"oslo","version":"^1.1.2"},{"name":"@sendgrid/mail","version":"^7.7.0"},{"name":"uuid","version":"^9.0.0"},{"name":"vitest","version":"^1.2.1"},{"name":"@vitest/ui","version":"^1.2.1"},{"name":"jsdom","version":"^21.1.1"},{"name":"@testing-library/react","version":"^14.1.2"},{"name":"@testing-library/jest-dom","version":"^6.3.0"},{"name":"msw","version":"^1.1.0"},{"name":"pg-boss","version":"^8.4.2"}],"devDependencies":[{"name":"@tsconfig/node18","version":"latest"}]},"_userNpmDeps":{"userDependencies":[{"name":"react","version":"^18.2.0"},{"name":"wasp","version":"file:.wasp/out/sdk/wasp"}],"userDevDependencies":[{"name":"@types/react","version":"^18.0.37"},{"name":"prisma","version":"4.16.2"},{"name":"typescript","version":"^5.1.0"},{"name":"vite","version":"^4.3.9"}]},"_waspFrameworkNpmDeps":{"npmDepsForWebApp":{"dependencies":[{"name":"@tanstack/react-query","version":"^4.29.0"},{"name":"axios","version":"^1.4.0"},{"name":"mitt","version":"3.0.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"react-router-dom","version":"^5.3.3"},{"name":"superjson","version":"^1.12.2"}],"devDependencies":[{"name":"@tsconfig/vite-react","version":"^2.0.0"},{"name":"@types/react-dom","version":"^18.0.11"},{"name":"@types/react-router-dom","version":"^5.3.3"},{"name":"@vitejs/plugin-react","version":"^4.2.1"},{"name":"dotenv","version":"^16.0.3"}]},"npmDepsForServer":{"dependencies":[{"name":"cookie-parser","version":"~1.4.6"},{"name":"cors","version":"^2.8.5"},{"name":"dotenv","version":"16.0.2"},{"name":"express","version":"~4.18.1"},{"name":"helmet","version":"^6.0.0"},{"name":"jsonwebtoken","version":"^8.5.1"},{"name":"morgan","version":"~1.10.0"},{"name":"passport","version":"0.6.0"},{"name":"passport-google-oauth20","version":"2.0.0"},{"name":"rate-limiter-flexible","version":"^2.4.1"},{"name":"superjson","version":"^1.12.2"}],"devDependencies":[{"name":"@tsconfig/node18","version":"latest"},{"name":"@types/cors","version":"^2.8.5"},{"name":"@types/express","version":"^4.17.13"},{"name":"@types/express-serve-static-core","version":"^4.17.13"},{"name":"@types/node","version":"^18.0.0"},{"name":"nodemon","version":"^2.0.19"},{"name":"rollup","version":"^4.9.6"},{"name":"rollup-plugin-esbuild","version":"^6.1.1"},{"name":"standard","version":"^17.0.0"}]}}}
|
@ -1,17 +1,16 @@
|
||||
import SecurePassword from 'secure-password'
|
||||
import { Argon2id } from 'oslo/password'
|
||||
|
||||
const SP = new SecurePassword()
|
||||
const argon2id = new Argon2id()
|
||||
|
||||
// PRIVATE API
|
||||
export const hashPassword = async (password: string): Promise<string> => {
|
||||
const hashedPwdBuffer = await SP.hash(Buffer.from(password))
|
||||
return hashedPwdBuffer.toString("base64")
|
||||
return argon2id.hash(password)
|
||||
}
|
||||
|
||||
// PRIVATE API
|
||||
export const verifyPassword = async (hashedPassword: string, password: string): Promise<void> => {
|
||||
const result = await SP.verify(Buffer.from(password), Buffer.from(hashedPassword, "base64"))
|
||||
if (result !== SecurePassword.VALID) {
|
||||
const isValidPassword = await argon2id.verify(hashedPassword, password)
|
||||
if (!isValidPassword) {
|
||||
throw new Error('Invalid password.')
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,13 @@
|
||||
import SecurePassword from 'secure-password';
|
||||
const SP = new SecurePassword();
|
||||
import { Argon2id } from 'oslo/password';
|
||||
const argon2id = new Argon2id();
|
||||
// PRIVATE API
|
||||
export const hashPassword = async (password) => {
|
||||
const hashedPwdBuffer = await SP.hash(Buffer.from(password));
|
||||
return hashedPwdBuffer.toString("base64");
|
||||
return argon2id.hash(password);
|
||||
};
|
||||
// PRIVATE API
|
||||
export const verifyPassword = async (hashedPassword, password) => {
|
||||
const result = await SP.verify(Buffer.from(password), Buffer.from(hashedPassword, "base64"));
|
||||
if (result !== SecurePassword.VALID) {
|
||||
const isValidPassword = await argon2id.verify(hashedPassword, password);
|
||||
if (!isValidPassword) {
|
||||
throw new Error('Invalid password.');
|
||||
}
|
||||
};
|
||||
|
@ -1 +1 @@
|
||||
{"version":3,"file":"password.js","sourceRoot":"","sources":["../../auth/password.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,MAAM,iBAAiB,CAAA;AAE5C,MAAM,EAAE,GAAG,IAAI,cAAc,EAAE,CAAA;AAE/B,cAAc;AACd,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAE,QAAgB,EAAmB,EAAE;IACtE,MAAM,eAAe,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC5D,OAAO,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;AAC3C,CAAC,CAAA;AAED,cAAc;AACd,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EAAE,cAAsB,EAAE,QAAgB,EAAiB,EAAE;IAC9F,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC,CAAA;IAC5F,IAAI,MAAM,KAAK,cAAc,CAAC,KAAK,EAAE;QACnC,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAA;KACrC;AACH,CAAC,CAAA"}
|
||||
{"version":3,"file":"password.js","sourceRoot":"","sources":["../../auth/password.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAExC,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAA;AAE/B,cAAc;AACd,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAE,QAAgB,EAAmB,EAAE;IACtE,OAAO,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;AAChC,CAAC,CAAA;AAED,cAAc;AACd,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EAAE,cAAsB,EAAE,QAAgB,EAAiB,EAAE;IAC9F,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAA;IACvE,IAAI,CAAC,eAAe,EAAE;QACpB,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAA;KACrC;AACH,CAAC,CAAA"}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@lucia-auth/adapter-prisma": "^4.0.0-beta.9",
|
||||
"@lucia-auth/adapter-prisma": "^4.0.0",
|
||||
"@prisma/client": "4.16.2",
|
||||
"@sendgrid/mail": "^7.7.0",
|
||||
"@stitches/react": "^1.2.8",
|
||||
@ -14,16 +14,15 @@
|
||||
"jsdom": "^21.1.1",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"lodash.merge": "^4.6.2",
|
||||
"lucia": "^3.0.0-beta.14",
|
||||
"lucia": "^3.0.1",
|
||||
"mitt": "3.0.0",
|
||||
"msw": "^1.1.0",
|
||||
"oslo": "^1.1.2",
|
||||
"pg-boss": "^8.4.2",
|
||||
"prisma": "4.16.2",
|
||||
"react": "^18.2.0",
|
||||
"react-hook-form": "^7.45.4",
|
||||
"react-router-dom": "^5.3.3",
|
||||
"secure-password": "^4.0.0",
|
||||
"sodium-native": "3.3.0",
|
||||
"superjson": "^1.12.2",
|
||||
"uuid": "^9.0.0",
|
||||
"vitest": "^1.2.1"
|
||||
|
@ -214,7 +214,7 @@
|
||||
"file",
|
||||
"../out/sdk/wasp/package.json"
|
||||
],
|
||||
"2088c007790071632d6fffacfe8fa531adc674ffbfcd8f9da8627318dff6707c"
|
||||
"7da143b79de48120d1d0ff96aa813f59ef44582c375cb3c624467cb9afa7223b"
|
||||
],
|
||||
[
|
||||
[
|
||||
|
@ -1 +1 @@
|
||||
{"_waspSdkNpmDeps":{"dependencies":[{"name":"@prisma/client","version":"4.16.2"},{"name":"prisma","version":"4.16.2"},{"name":"@tanstack/react-query","version":"^4.29.0"},{"name":"axios","version":"^1.4.0"},{"name":"express","version":"~4.18.1"},{"name":"jsonwebtoken","version":"^8.5.1"},{"name":"mitt","version":"3.0.0"},{"name":"react","version":"^18.2.0"},{"name":"lodash.merge","version":"^4.6.2"},{"name":"react-router-dom","version":"^5.3.3"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"secure-password","version":"^4.0.0"},{"name":"sodium-native","version":"3.3.0"},{"name":"superjson","version":"^1.12.2"},{"name":"@types/express-serve-static-core","version":"^4.17.13"},{"name":"uuid","version":"^9.0.0"},{"name":"vitest","version":"^1.2.1"},{"name":"@vitest/ui","version":"^1.2.1"},{"name":"jsdom","version":"^21.1.1"},{"name":"@testing-library/react","version":"^14.1.2"},{"name":"@testing-library/jest-dom","version":"^6.3.0"},{"name":"msw","version":"^1.1.0"},{"name":"pg-boss","version":"^8.4.2"}],"devDependencies":[{"name":"@tsconfig/node18","version":"latest"}]},"_userNpmDeps":{"userDependencies":[{"name":"react","version":"^18.2.0"},{"name":"wasp","version":"file:.wasp/out/sdk/wasp"}],"userDevDependencies":[{"name":"@types/react","version":"^18.0.37"},{"name":"prisma","version":"4.16.2"},{"name":"typescript","version":"^5.1.0"},{"name":"vite","version":"^4.3.9"}]},"_waspFrameworkNpmDeps":{"npmDepsForWebApp":{"dependencies":[{"name":"@tanstack/react-query","version":"^4.29.0"},{"name":"axios","version":"^1.4.0"},{"name":"mitt","version":"3.0.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"react-router-dom","version":"^5.3.3"},{"name":"superjson","version":"^1.12.2"}],"devDependencies":[{"name":"@tsconfig/vite-react","version":"^2.0.0"},{"name":"@types/react-dom","version":"^18.0.11"},{"name":"@types/react-router-dom","version":"^5.3.3"},{"name":"@vitejs/plugin-react","version":"^4.2.1"},{"name":"dotenv","version":"^16.0.3"}]},"npmDepsForServer":{"dependencies":[{"name":"cookie-parser","version":"~1.4.6"},{"name":"cors","version":"^2.8.5"},{"name":"dotenv","version":"16.0.2"},{"name":"express","version":"~4.18.1"},{"name":"helmet","version":"^6.0.0"},{"name":"jsonwebtoken","version":"^8.5.1"},{"name":"morgan","version":"~1.10.0"},{"name":"rate-limiter-flexible","version":"^2.4.1"},{"name":"superjson","version":"^1.12.2"}],"devDependencies":[{"name":"@tsconfig/node18","version":"latest"},{"name":"@types/cors","version":"^2.8.5"},{"name":"@types/express","version":"^4.17.13"},{"name":"@types/express-serve-static-core","version":"^4.17.13"},{"name":"@types/node","version":"^18.0.0"},{"name":"nodemon","version":"^2.0.19"},{"name":"rollup","version":"^4.9.6"},{"name":"rollup-plugin-esbuild","version":"^6.1.1"},{"name":"standard","version":"^17.0.0"}]}}}
|
||||
{"_waspSdkNpmDeps":{"dependencies":[{"name":"@prisma/client","version":"4.16.2"},{"name":"prisma","version":"4.16.2"},{"name":"@tanstack/react-query","version":"^4.29.0"},{"name":"axios","version":"^1.4.0"},{"name":"express","version":"~4.18.1"},{"name":"jsonwebtoken","version":"^8.5.1"},{"name":"mitt","version":"3.0.0"},{"name":"react","version":"^18.2.0"},{"name":"lodash.merge","version":"^4.6.2"},{"name":"react-router-dom","version":"^5.3.3"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"superjson","version":"^1.12.2"},{"name":"@types/express-serve-static-core","version":"^4.17.13"},{"name":"uuid","version":"^9.0.0"},{"name":"vitest","version":"^1.2.1"},{"name":"@vitest/ui","version":"^1.2.1"},{"name":"jsdom","version":"^21.1.1"},{"name":"@testing-library/react","version":"^14.1.2"},{"name":"@testing-library/jest-dom","version":"^6.3.0"},{"name":"msw","version":"^1.1.0"},{"name":"pg-boss","version":"^8.4.2"}],"devDependencies":[{"name":"@tsconfig/node18","version":"latest"}]},"_userNpmDeps":{"userDependencies":[{"name":"react","version":"^18.2.0"},{"name":"wasp","version":"file:.wasp/out/sdk/wasp"}],"userDevDependencies":[{"name":"@types/react","version":"^18.0.37"},{"name":"prisma","version":"4.16.2"},{"name":"typescript","version":"^5.1.0"},{"name":"vite","version":"^4.3.9"}]},"_waspFrameworkNpmDeps":{"npmDepsForWebApp":{"dependencies":[{"name":"@tanstack/react-query","version":"^4.29.0"},{"name":"axios","version":"^1.4.0"},{"name":"mitt","version":"3.0.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"react-router-dom","version":"^5.3.3"},{"name":"superjson","version":"^1.12.2"}],"devDependencies":[{"name":"@tsconfig/vite-react","version":"^2.0.0"},{"name":"@types/react-dom","version":"^18.0.11"},{"name":"@types/react-router-dom","version":"^5.3.3"},{"name":"@vitejs/plugin-react","version":"^4.2.1"},{"name":"dotenv","version":"^16.0.3"}]},"npmDepsForServer":{"dependencies":[{"name":"cookie-parser","version":"~1.4.6"},{"name":"cors","version":"^2.8.5"},{"name":"dotenv","version":"16.0.2"},{"name":"express","version":"~4.18.1"},{"name":"helmet","version":"^6.0.0"},{"name":"jsonwebtoken","version":"^8.5.1"},{"name":"morgan","version":"~1.10.0"},{"name":"rate-limiter-flexible","version":"^2.4.1"},{"name":"superjson","version":"^1.12.2"}],"devDependencies":[{"name":"@tsconfig/node18","version":"latest"},{"name":"@types/cors","version":"^2.8.5"},{"name":"@types/express","version":"^4.17.13"},{"name":"@types/express-serve-static-core","version":"^4.17.13"},{"name":"@types/node","version":"^18.0.0"},{"name":"nodemon","version":"^2.0.19"},{"name":"rollup","version":"^4.9.6"},{"name":"rollup-plugin-esbuild","version":"^6.1.1"},{"name":"standard","version":"^17.0.0"}]}}}
|
@ -18,8 +18,6 @@
|
||||
"react": "^18.2.0",
|
||||
"react-hook-form": "^7.45.4",
|
||||
"react-router-dom": "^5.3.3",
|
||||
"secure-password": "^4.0.0",
|
||||
"sodium-native": "3.3.0",
|
||||
"superjson": "^1.12.2",
|
||||
"uuid": "^9.0.0",
|
||||
"vitest": "^1.2.1"
|
||||
|
@ -207,7 +207,7 @@
|
||||
"file",
|
||||
"../out/sdk/wasp/package.json"
|
||||
],
|
||||
"8c4e7254985043dbada72ea8caa14dc82e154e5d1d3384677b7986f9ba8ef833"
|
||||
"6691a48b86fa7e4133f01e647534c32c378755b9c4f266853fdcdc61907e711c"
|
||||
],
|
||||
[
|
||||
[
|
||||
|
@ -1 +1 @@
|
||||
{"_waspSdkNpmDeps":{"dependencies":[{"name":"@prisma/client","version":"4.16.2"},{"name":"prisma","version":"4.16.2"},{"name":"@tanstack/react-query","version":"^4.29.0"},{"name":"axios","version":"^1.4.0"},{"name":"express","version":"~4.18.1"},{"name":"jsonwebtoken","version":"^8.5.1"},{"name":"mitt","version":"3.0.0"},{"name":"react","version":"^18.2.0"},{"name":"lodash.merge","version":"^4.6.2"},{"name":"react-router-dom","version":"^5.3.3"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"secure-password","version":"^4.0.0"},{"name":"sodium-native","version":"3.3.0"},{"name":"superjson","version":"^1.12.2"},{"name":"@types/express-serve-static-core","version":"^4.17.13"},{"name":"uuid","version":"^9.0.0"},{"name":"vitest","version":"^1.2.1"},{"name":"@vitest/ui","version":"^1.2.1"},{"name":"jsdom","version":"^21.1.1"},{"name":"@testing-library/react","version":"^14.1.2"},{"name":"@testing-library/jest-dom","version":"^6.3.0"},{"name":"msw","version":"^1.1.0"}],"devDependencies":[{"name":"@tsconfig/node18","version":"latest"}]},"_userNpmDeps":{"userDependencies":[{"name":"react","version":"^18.2.0"},{"name":"wasp","version":"file:.wasp/out/sdk/wasp"}],"userDevDependencies":[{"name":"@types/react","version":"^18.0.37"},{"name":"prisma","version":"4.16.2"},{"name":"typescript","version":"^5.1.0"},{"name":"vite","version":"^4.3.9"}]},"_waspFrameworkNpmDeps":{"npmDepsForWebApp":{"dependencies":[{"name":"@tanstack/react-query","version":"^4.29.0"},{"name":"axios","version":"^1.4.0"},{"name":"mitt","version":"3.0.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"react-router-dom","version":"^5.3.3"},{"name":"superjson","version":"^1.12.2"}],"devDependencies":[{"name":"@tsconfig/vite-react","version":"^2.0.0"},{"name":"@types/react-dom","version":"^18.0.11"},{"name":"@types/react-router-dom","version":"^5.3.3"},{"name":"@vitejs/plugin-react","version":"^4.2.1"},{"name":"dotenv","version":"^16.0.3"}]},"npmDepsForServer":{"dependencies":[{"name":"cookie-parser","version":"~1.4.6"},{"name":"cors","version":"^2.8.5"},{"name":"dotenv","version":"16.0.2"},{"name":"express","version":"~4.18.1"},{"name":"helmet","version":"^6.0.0"},{"name":"jsonwebtoken","version":"^8.5.1"},{"name":"morgan","version":"~1.10.0"},{"name":"rate-limiter-flexible","version":"^2.4.1"},{"name":"superjson","version":"^1.12.2"}],"devDependencies":[{"name":"@tsconfig/node18","version":"latest"},{"name":"@types/cors","version":"^2.8.5"},{"name":"@types/express","version":"^4.17.13"},{"name":"@types/express-serve-static-core","version":"^4.17.13"},{"name":"@types/node","version":"^18.0.0"},{"name":"nodemon","version":"^2.0.19"},{"name":"rollup","version":"^4.9.6"},{"name":"rollup-plugin-esbuild","version":"^6.1.1"},{"name":"standard","version":"^17.0.0"}]}}}
|
||||
{"_waspSdkNpmDeps":{"dependencies":[{"name":"@prisma/client","version":"4.16.2"},{"name":"prisma","version":"4.16.2"},{"name":"@tanstack/react-query","version":"^4.29.0"},{"name":"axios","version":"^1.4.0"},{"name":"express","version":"~4.18.1"},{"name":"jsonwebtoken","version":"^8.5.1"},{"name":"mitt","version":"3.0.0"},{"name":"react","version":"^18.2.0"},{"name":"lodash.merge","version":"^4.6.2"},{"name":"react-router-dom","version":"^5.3.3"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"superjson","version":"^1.12.2"},{"name":"@types/express-serve-static-core","version":"^4.17.13"},{"name":"uuid","version":"^9.0.0"},{"name":"vitest","version":"^1.2.1"},{"name":"@vitest/ui","version":"^1.2.1"},{"name":"jsdom","version":"^21.1.1"},{"name":"@testing-library/react","version":"^14.1.2"},{"name":"@testing-library/jest-dom","version":"^6.3.0"},{"name":"msw","version":"^1.1.0"}],"devDependencies":[{"name":"@tsconfig/node18","version":"latest"}]},"_userNpmDeps":{"userDependencies":[{"name":"react","version":"^18.2.0"},{"name":"wasp","version":"file:.wasp/out/sdk/wasp"}],"userDevDependencies":[{"name":"@types/react","version":"^18.0.37"},{"name":"prisma","version":"4.16.2"},{"name":"typescript","version":"^5.1.0"},{"name":"vite","version":"^4.3.9"}]},"_waspFrameworkNpmDeps":{"npmDepsForWebApp":{"dependencies":[{"name":"@tanstack/react-query","version":"^4.29.0"},{"name":"axios","version":"^1.4.0"},{"name":"mitt","version":"3.0.0"},{"name":"react-dom","version":"^18.2.0"},{"name":"react-hook-form","version":"^7.45.4"},{"name":"react-router-dom","version":"^5.3.3"},{"name":"superjson","version":"^1.12.2"}],"devDependencies":[{"name":"@tsconfig/vite-react","version":"^2.0.0"},{"name":"@types/react-dom","version":"^18.0.11"},{"name":"@types/react-router-dom","version":"^5.3.3"},{"name":"@vitejs/plugin-react","version":"^4.2.1"},{"name":"dotenv","version":"^16.0.3"}]},"npmDepsForServer":{"dependencies":[{"name":"cookie-parser","version":"~1.4.6"},{"name":"cors","version":"^2.8.5"},{"name":"dotenv","version":"16.0.2"},{"name":"express","version":"~4.18.1"},{"name":"helmet","version":"^6.0.0"},{"name":"jsonwebtoken","version":"^8.5.1"},{"name":"morgan","version":"~1.10.0"},{"name":"rate-limiter-flexible","version":"^2.4.1"},{"name":"superjson","version":"^1.12.2"}],"devDependencies":[{"name":"@tsconfig/node18","version":"latest"},{"name":"@types/cors","version":"^2.8.5"},{"name":"@types/express","version":"^4.17.13"},{"name":"@types/express-serve-static-core","version":"^4.17.13"},{"name":"@types/node","version":"^18.0.0"},{"name":"nodemon","version":"^2.0.19"},{"name":"rollup","version":"^4.9.6"},{"name":"rollup-plugin-esbuild","version":"^6.1.1"},{"name":"standard","version":"^17.0.0"}]}}}
|
@ -17,8 +17,6 @@
|
||||
"react": "^18.2.0",
|
||||
"react-hook-form": "^7.45.4",
|
||||
"react-router-dom": "^5.3.3",
|
||||
"secure-password": "^4.0.0",
|
||||
"sodium-native": "3.3.0",
|
||||
"superjson": "^1.12.2",
|
||||
"uuid": "^9.0.0",
|
||||
"vitest": "^1.2.1"
|
||||
|
1172
waspc/examples/todoApp/package-lock.json
generated
1172
waspc/examples/todoApp/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -211,21 +211,6 @@ npmDepsForSdk spec =
|
||||
("lodash.merge", "^4.6.2"),
|
||||
("react-router-dom", "^5.3.3"),
|
||||
("react-hook-form", "^7.45.4"),
|
||||
("secure-password", "^4.0.0"),
|
||||
-- Secure-password 4.0.0. defaults to using sodium-native 3.4.1.,
|
||||
-- which segfaults on on Alpine:
|
||||
-- https://github.com/sodium-friends/sodium-native/issues/160
|
||||
--
|
||||
-- Before 0.12.0 (i.e., restructuring), we made Wasp use
|
||||
-- sodium-native 3.3.0. with package.json overrides in our web-app/package.json:
|
||||
-- https://github.com/wasp-lang/wasp/pull/729
|
||||
--
|
||||
-- Because our code that uses secure-password now lives in the SDK,
|
||||
-- and NPM apparently ignores package.json overrides for
|
||||
-- dependencies (no reference, found out by trying it out), the only
|
||||
-- way to force NPM to install sodium-native 3.3.0 is by listing it
|
||||
-- as a direct dependency.
|
||||
("sodium-native", "3.3.0"),
|
||||
("superjson", "^1.12.2"),
|
||||
("@types/express-serve-static-core", "^4.17.13")
|
||||
]
|
||||
|
@ -91,6 +91,7 @@ depsRequiredByAuth spec = maybe [] (const authDeps) maybeAuth
|
||||
maybeAuth = AS.App.auth $ snd $ getApp spec
|
||||
authDeps =
|
||||
AS.Dependency.fromList
|
||||
[ ("lucia", "^3.0.0-beta.14"),
|
||||
("@lucia-auth/adapter-prisma", "^4.0.0-beta.9")
|
||||
[ ("lucia", "^3.0.1"),
|
||||
("@lucia-auth/adapter-prisma", "^4.0.0"),
|
||||
("oslo", "^1.1.2")
|
||||
]
|
||||
|
@ -56,7 +56,7 @@ The main differences are:
|
||||
|
||||
- The server/client code separation is no longer necessary. You can now organize
|
||||
your code however you want, as long as it's inside the `src` directory.
|
||||
- All external imports in your Wasp file must have paths starting with `@src` (e.g., `import foo from '@src/bar.js')
|
||||
- All external imports in your Wasp file must have paths starting with `@src` (e.g., `import foo from '@src/bar.js'`)
|
||||
where `@src` refers to the `src` directory in your project root. The paths can
|
||||
no longer start with `@server` or `@client`.
|
||||
- Your project now features a top-level `public` dir. Wasp will publicly serve
|
||||
@ -438,6 +438,322 @@ The migration functions provided below are written with the typical use cases in
|
||||
|
||||
##### Username & Password
|
||||
|
||||
:::caution Users will need to migrate their password
|
||||
There is a breaking change between the old and the new auth in the way the password is hashed. This means that users will need to migrate their password after the migration, as the old password will no longer work.
|
||||
|
||||
Since the only way users using username and password as a login method can verify their identity is by providing both their username and password (there is no email or any other info, unless you asked for it and stored it explicitly), we need to provide them a way to exchange their old password for a new password. One way to handle this is to inform them about the need to migrate their password (on the login page) and provide a custom page to migrate the password.
|
||||
:::
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
Steps to create a custom page for migrating the password
|
||||
</summary>
|
||||
|
||||
1. You will need to install the `secure-password` and `sodium-native` packages to use the old hashing algorithm:
|
||||
|
||||
```bash
|
||||
npm install secure-password@4.0.0 sodium-native@3.3.0 --save-exact
|
||||
```
|
||||
|
||||
Make sure to save the exact versions of the packages.
|
||||
|
||||
2. Then you'll need to create a new page in your app where users can migrate their password. You can use the following code as a starting point:
|
||||
|
||||
<Tabs groupId="js-ts">
|
||||
<TabItem value="js" label="JavaScript">
|
||||
|
||||
```jsx title="src/pages/MigratePasswordPage.jsx"
|
||||
import {
|
||||
FormItemGroup,
|
||||
FormLabel,
|
||||
FormInput,
|
||||
FormError,
|
||||
} from "wasp/client/auth";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { migratePassword } from "wasp/client/operations";
|
||||
import { useState } from "react";
|
||||
|
||||
export function MigratePasswordPage() {
|
||||
const [successMessage, setSuccessMessage] = useState(null);
|
||||
const [errorMessage, setErrorMessage] = useState(null);
|
||||
const form = useForm({
|
||||
defaultValues: {
|
||||
username: "",
|
||||
password: "",
|
||||
},
|
||||
});
|
||||
|
||||
const onSubmit = form.handleSubmit(async (data) => {
|
||||
try {
|
||||
const result = await migratePassword(data);
|
||||
setSuccessMessage(result.message);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
if (e instanceof Error) {
|
||||
setErrorMessage(e.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<div style={{
|
||||
maxWidth: "400px",
|
||||
margin: "auto",
|
||||
}}>
|
||||
<h1>Migrate your password</h1>
|
||||
<p>
|
||||
If you have an account on the old version of the website, you can
|
||||
migrate your password to the new version.
|
||||
</p>
|
||||
{successMessage && <div>{successMessage}</div>}
|
||||
{errorMessage && <FormError>{errorMessage}</FormError>}
|
||||
<form onSubmit={onSubmit}>
|
||||
<FormItemGroup>
|
||||
<FormLabel>Username</FormLabel>
|
||||
<FormInput
|
||||
{...form.register("username", {
|
||||
required: "Username is required",
|
||||
})}
|
||||
/>
|
||||
<FormError>{form.formState.errors.username?.message}</FormError>
|
||||
</FormItemGroup>
|
||||
<FormItemGroup>
|
||||
<FormLabel>Password</FormLabel>
|
||||
<FormInput
|
||||
{...form.register("password", {
|
||||
required: "Password is required",
|
||||
})}
|
||||
type="password"
|
||||
/>
|
||||
<FormError>{form.formState.errors.password?.message}</FormError>
|
||||
</FormItemGroup>
|
||||
<button type="submit">Migrate password</button>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="ts" label="TypeScript">
|
||||
|
||||
```tsx title="src/pages/MigratePasswordPage.tsx"
|
||||
import {
|
||||
FormItemGroup,
|
||||
FormLabel,
|
||||
FormInput,
|
||||
FormError,
|
||||
} from "wasp/client/auth";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { migratePassword } from "wasp/client/operations";
|
||||
import { useState } from "react";
|
||||
|
||||
export function MigratePasswordPage() {
|
||||
const [successMessage, setSuccessMessage] = useState<string | null>(null);
|
||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||
const form = useForm<{
|
||||
username: string;
|
||||
password: string;
|
||||
}>();
|
||||
|
||||
const onSubmit = form.handleSubmit(async (data) => {
|
||||
try {
|
||||
const result = await migratePassword(data);
|
||||
setSuccessMessage(result.message);
|
||||
} catch (e: unknown) {
|
||||
console.error(e);
|
||||
if (e instanceof Error) {
|
||||
setErrorMessage(e.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<div style={{
|
||||
maxWidth: "400px",
|
||||
margin: "auto",
|
||||
}}>
|
||||
<h1>Migrate your password</h1>
|
||||
<p>
|
||||
If you have an account on the old version of the website, you can
|
||||
migrate your password to the new version.
|
||||
</p>
|
||||
{successMessage && <div>{successMessage}</div>}
|
||||
{errorMessage && <FormError>{errorMessage}</FormError>}
|
||||
<form onSubmit={onSubmit}>
|
||||
<FormItemGroup>
|
||||
<FormLabel>Username</FormLabel>
|
||||
<FormInput
|
||||
{...form.register("username", {
|
||||
required: "Username is required",
|
||||
})}
|
||||
/>
|
||||
<FormError>{form.formState.errors.username?.message}</FormError>
|
||||
</FormItemGroup>
|
||||
<FormItemGroup>
|
||||
<FormLabel>Password</FormLabel>
|
||||
<FormInput
|
||||
{...form.register("password", {
|
||||
required: "Password is required",
|
||||
})}
|
||||
type="password"
|
||||
/>
|
||||
<FormError>{form.formState.errors.password?.message}</FormError>
|
||||
</FormItemGroup>
|
||||
<button type="submit">Migrate password</button>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
3. Finally, you will need to create a new operation in your app to handle the password migration. You can use the following code as a starting point:
|
||||
|
||||
|
||||
<Tabs groupId="js-ts">
|
||||
<TabItem value="js" label="JavaScript">
|
||||
|
||||
```wasp title="main.wasp"
|
||||
action migratePassword {
|
||||
fn: import { migratePassword } from "@src/auth",
|
||||
entities: []
|
||||
}
|
||||
```
|
||||
|
||||
```js title="src/auth.js"
|
||||
import SecurePassword from "secure-password";
|
||||
import { HttpError } from "wasp/server";
|
||||
import {
|
||||
createProviderId,
|
||||
deserializeAndSanitizeProviderData,
|
||||
findAuthIdentity,
|
||||
updateAuthIdentityProviderData,
|
||||
} from "wasp/server/auth";
|
||||
|
||||
export const migratePassword = async ({ password, username }, _context) => {
|
||||
const providerId = createProviderId("username", username);
|
||||
const authIdentity = await findAuthIdentity(providerId);
|
||||
|
||||
if (!authIdentity) {
|
||||
throw new HttpError(400, "Something went wrong");
|
||||
}
|
||||
|
||||
const providerData =
|
||||
deserializeAndSanitizeProviderData < "username" > authIdentity.providerData;
|
||||
|
||||
try {
|
||||
const SP = new SecurePassword();
|
||||
|
||||
// This will verify the password using the old algorithm
|
||||
const result = await SP.verify(
|
||||
Buffer.from(password),
|
||||
Buffer.from(providerData.hashedPassword, "base64")
|
||||
);
|
||||
|
||||
if (result !== SecurePassword.VALID) {
|
||||
throw new HttpError(400, "Something went wrong");
|
||||
}
|
||||
|
||||
// This will hash the password using the new algorithm and update the
|
||||
// provider data in the database.
|
||||
(await updateAuthIdentityProviderData) <
|
||||
"username" >
|
||||
(providerId,
|
||||
providerData,
|
||||
{
|
||||
hashedPassword: password,
|
||||
});
|
||||
} catch (e) {
|
||||
throw new HttpError(400, "Something went wrong");
|
||||
}
|
||||
|
||||
return {
|
||||
message: "Password migrated successfully.",
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="ts" label="TypeScript">
|
||||
|
||||
```wasp title="main.wasp"
|
||||
action migratePassword {
|
||||
fn: import { migratePassword } from "@src/auth",
|
||||
entities: []
|
||||
}
|
||||
```
|
||||
|
||||
```ts title="src/auth.ts"
|
||||
import SecurePassword from "secure-password";
|
||||
import { HttpError } from "wasp/server";
|
||||
import {
|
||||
createProviderId,
|
||||
deserializeAndSanitizeProviderData,
|
||||
findAuthIdentity,
|
||||
updateAuthIdentityProviderData,
|
||||
} from "wasp/server/auth";
|
||||
import { MigratePassword } from "wasp/server/operations";
|
||||
|
||||
type MigratePasswordInput = {
|
||||
username: string;
|
||||
password: string;
|
||||
};
|
||||
type MigratePasswordOutput = {
|
||||
message: string;
|
||||
};
|
||||
|
||||
export const migratePassword: MigratePassword<
|
||||
MigratePasswordInput,
|
||||
MigratePasswordOutput
|
||||
> = async ({ password, username }, _context) => {
|
||||
const providerId = createProviderId("username", username);
|
||||
const authIdentity = await findAuthIdentity(providerId);
|
||||
|
||||
if (!authIdentity) {
|
||||
throw new HttpError(400, "Something went wrong");
|
||||
}
|
||||
|
||||
const providerData = deserializeAndSanitizeProviderData<"username">(
|
||||
authIdentity.providerData
|
||||
);
|
||||
|
||||
try {
|
||||
const SP = new SecurePassword();
|
||||
|
||||
// This will verify the password using the old algorithm
|
||||
const result = await SP.verify(
|
||||
Buffer.from(password),
|
||||
Buffer.from(providerData.hashedPassword, "base64")
|
||||
);
|
||||
|
||||
if (result !== SecurePassword.VALID) {
|
||||
throw new HttpError(400, "Something went wrong");
|
||||
}
|
||||
|
||||
// This will hash the password using the new algorithm and update the
|
||||
// provider data in the database.
|
||||
await updateAuthIdentityProviderData<"username">(providerId, providerData, {
|
||||
hashedPassword: password,
|
||||
});
|
||||
} catch (e) {
|
||||
throw new HttpError(400, "Something went wrong");
|
||||
}
|
||||
|
||||
return {
|
||||
message: "Password migrated successfully.",
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
```ts title="src/migrateToNewAuth.ts"
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import { ProviderName, UsernameProviderData } from "wasp/server/auth";
|
||||
@ -488,6 +804,14 @@ export async function migrateUsernameAuth(prismaClient: PrismaClient) {
|
||||
|
||||
##### Email
|
||||
|
||||
:::caution Users will need to reset their password
|
||||
|
||||
There is a breaking change between the old and the new auth in the way the password is hashed. This means that users will need to reset their password after the migration, as the old password will no longer work.
|
||||
|
||||
It would be best to notify your users about this change and put a notice on your login page to **request a password reset**.
|
||||
|
||||
:::
|
||||
|
||||
```ts title="src/migrateToNewAuth.ts"
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import { EmailProviderData, ProviderName } from "wasp/server/auth";
|
||||
|
Loading…
Reference in New Issue
Block a user