mirror of https://github.com/wg-easy/wg-easy
Browse Source
* separate route for onboarding * zse zod for validation * use argon2id * add build toolspull/1648/head
committed by
Bernd Storath
17 changed files with 104 additions and 126 deletions
@ -26,12 +26,12 @@ importers: |
|||
apexcharts: |
|||
specifier: ^3.53.0 |
|||
version: 3.53.0 |
|||
argon2: |
|||
specifier: ^0.41.1 |
|||
version: 0.41.1 |
|||
basic-auth: |
|||
specifier: ^2.0.1 |
|||
version: 2.0.1 |
|||
bcryptjs: |
|||
specifier: ^2.4.3 |
|||
version: 2.4.3 |
|||
cidr-tools: |
|||
specifier: ^11.0.2 |
|||
version: 11.0.2 |
|||
@ -81,9 +81,6 @@ importers: |
|||
'@nuxt/eslint-config': |
|||
specifier: ^0.5.5 |
|||
version: 0.5.5([email protected]([email protected]))([email protected]) |
|||
'@types/bcryptjs': |
|||
specifier: ^2.4.6 |
|||
version: 2.4.6 |
|||
'@types/debug': |
|||
specifier: ^4.1.12 |
|||
version: 4.1.12 |
|||
@ -1013,6 +1010,10 @@ packages: |
|||
resolution: {integrity: sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==} |
|||
engines: {node: '>= 10.0.0'} |
|||
|
|||
'@phc/[email protected]': |
|||
resolution: {integrity: sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==} |
|||
engines: {node: '>=10'} |
|||
|
|||
'@pinia/[email protected]': |
|||
resolution: {integrity: sha512-nNEs2pq6+Ji5qIyRwmeD9LUdctL8aJ8QMVLTYxUc16cXEOcIIN+MSA8Xudsd0lVETYgEAROT5HiBHnOYRDY3yQ==} |
|||
|
|||
@ -1211,9 +1212,6 @@ packages: |
|||
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} |
|||
engines: {node: '>=10.13.0'} |
|||
|
|||
'@types/[email protected]': |
|||
resolution: {integrity: sha512-9xlo6R2qDs5uixm0bcIqCeMCE6HiQsIyel9KQySStiyqNl2tnj2mP3DX1Nf56MD6KMenNNlBBsy3LJ7gUEQPXQ==} |
|||
|
|||
'@types/[email protected]': |
|||
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} |
|||
|
|||
@ -1520,6 +1518,10 @@ packages: |
|||
[email protected]: |
|||
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} |
|||
|
|||
[email protected]: |
|||
resolution: {integrity: sha512-dqCW8kJXke8Ik+McUcMDltrbuAWETPyU6iq+4AhxqKphWi7pChB/Zgd/Tp/o8xRLbg8ksMj46F/vph9wnxpTzQ==} |
|||
engines: {node: '>=16.17.0'} |
|||
|
|||
[email protected]: |
|||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} |
|||
|
|||
@ -1567,9 +1569,6 @@ packages: |
|||
resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==} |
|||
engines: {node: '>= 0.8'} |
|||
|
|||
[email protected]: |
|||
resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==} |
|||
|
|||
[email protected]: |
|||
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} |
|||
engines: {node: '>=8'} |
|||
@ -3031,6 +3030,10 @@ packages: |
|||
[email protected]: |
|||
resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} |
|||
|
|||
[email protected]: |
|||
resolution: {integrity: sha512-yBY+qqWSv3dWKGODD6OGE6GnTX7Q2r+4+DfpqxHSHh8x0B4EKP9+wVGLS6U/AM1vxSNNmUEuIV5EGhYwPpfOwQ==} |
|||
engines: {node: ^18 || ^20 || >= 21} |
|||
|
|||
[email protected]: |
|||
resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} |
|||
|
|||
@ -5484,6 +5487,8 @@ snapshots: |
|||
'@parcel/watcher-win32-ia32': 2.4.1 |
|||
'@parcel/watcher-win32-x64': 2.4.1 |
|||
|
|||
'@phc/[email protected]': {} |
|||
|
|||
'@pinia/[email protected]([email protected])([email protected])([email protected])([email protected]([email protected]))': |
|||
dependencies: |
|||
'@nuxt/kit': 3.13.0([email protected])([email protected]) |
|||
@ -5651,8 +5656,6 @@ snapshots: |
|||
|
|||
'@trysound/[email protected]': {} |
|||
|
|||
'@types/[email protected]': {} |
|||
|
|||
'@types/[email protected]': |
|||
dependencies: |
|||
'@types/ms': 0.7.34 |
|||
@ -6082,6 +6085,12 @@ snapshots: |
|||
|
|||
[email protected]: {} |
|||
|
|||
[email protected]: |
|||
dependencies: |
|||
'@phc/format': 1.0.0 |
|||
node-addon-api: 8.1.0 |
|||
node-gyp-build: 4.8.2 |
|||
|
|||
[email protected]: {} |
|||
|
|||
[email protected]: |
|||
@ -6127,8 +6136,6 @@ snapshots: |
|||
dependencies: |
|||
safe-buffer: 5.1.2 |
|||
|
|||
[email protected]: {} |
|||
|
|||
[email protected]: {} |
|||
|
|||
[email protected]: |
|||
@ -7727,6 +7734,8 @@ snapshots: |
|||
|
|||
[email protected]: {} |
|||
|
|||
[email protected]: {} |
|||
|
|||
[email protected]: {} |
|||
|
|||
[email protected]: |
|||
|
@ -0,0 +1,8 @@ |
|||
export default defineEventHandler(async (event) => { |
|||
const { username, password } = await readValidatedBody( |
|||
event, |
|||
validateZod(passwordType) |
|||
); |
|||
await Database.createUser(username, password); |
|||
return { success: true }; |
|||
}); |
@ -1,24 +0,0 @@ |
|||
import { DatabaseError } from '~~/services/database/repositories/database'; |
|||
|
|||
export default defineEventHandler(async (event) => { |
|||
setHeader(event, 'Content-Type', 'application/json'); |
|||
try { |
|||
const { username, password } = await readValidatedBody( |
|||
event, |
|||
validateZod(passwordType) |
|||
); |
|||
await Database.newUserWithPassword(username, password); |
|||
return { success: true }; |
|||
} catch (error) { |
|||
if (error instanceof DatabaseError) { |
|||
const t = await useTranslation(event); |
|||
throw createError({ |
|||
statusCode: 400, |
|||
statusMessage: t(error.message), |
|||
message: error.message, |
|||
}); |
|||
} else { |
|||
throw createError('Something happened !'); |
|||
} |
|||
} |
|||
}); |
@ -0,0 +1,15 @@ |
|||
export default defineEventHandler(async (event) => { |
|||
const { username, password } = await readValidatedBody( |
|||
event, |
|||
validateZod(passwordType) |
|||
); |
|||
const users = await Database.getUsers(); |
|||
if (users.length !== 0) { |
|||
throw createError({ |
|||
statusCode: 400, |
|||
statusMessage: 'Invalid state', |
|||
}); |
|||
} |
|||
await Database.createUser(username, password); |
|||
return { success: true }; |
|||
}); |
@ -1,47 +1,18 @@ |
|||
import bcrypt from 'bcryptjs'; |
|||
import argon2 from 'argon2'; |
|||
|
|||
/** |
|||
* Checks if `password` matches the user password. |
|||
* |
|||
* @param {string} password string to test |
|||
* @returns {boolean} `true` if matching user password, otherwise `false` |
|||
* Checks if `password` matches the hash. |
|||
*/ |
|||
export function isPasswordValid(password: string, hash: string): boolean { |
|||
return bcrypt.compareSync(password, hash); |
|||
} |
|||
|
|||
/** |
|||
* Checks if a password is strong based on following criteria : |
|||
* |
|||
* - minimum length of 12 characters |
|||
* - contains at least one uppercase letter |
|||
* - contains at least one lowercase letter |
|||
* - contains at least one number |
|||
* - contains at least one special character (e.g., !@#$%^&*(),.?":{}|<>). |
|||
* |
|||
* @param {string} password - The password to validate |
|||
* @returns {boolean} `true` if the password is strong, otherwise `false` |
|||
*/ |
|||
|
|||
export function isPasswordStrong(password: string): boolean { |
|||
if (password.length < 12) { |
|||
return false; |
|||
} |
|||
|
|||
const hasUpperCase = /[A-Z]/.test(password); |
|||
const hasLowerCase = /[a-z]/.test(password); |
|||
const hasNumber = /\d/.test(password); |
|||
const hasSpecialChar = /[!@#$%^&*(),.?":{}|<>]/.test(password); |
|||
|
|||
return hasUpperCase && hasLowerCase && hasNumber && hasSpecialChar; |
|||
export function isPasswordValid( |
|||
password: string, |
|||
hash: string |
|||
): Promise<boolean> { |
|||
return argon2.verify(hash, password); |
|||
} |
|||
|
|||
/** |
|||
* Hashes a password. |
|||
* |
|||
* @param {string} password - The plaintext password to hash |
|||
* @returns {string} The hash of the password |
|||
*/ |
|||
export function hashPassword(password: string): string { |
|||
return bcrypt.hashSync(password, 12); |
|||
export async function hashPassword(password: string): Promise<string> { |
|||
return argon2.hash(password); |
|||
} |
|||
|
Loading…
Reference in new issue