Skip to content

Commit ad04611

Browse files
committed
refactor: 💡 Added passwords hashing using bcrypt
1 parent 8f0beca commit ad04611

File tree

6 files changed

+31
-60
lines changed

6 files changed

+31
-60
lines changed

‎package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
"@types/debug": "^4.1.8",
7777
"@types/luxon": "^3.3.0",
7878
"@types/jsonwebtoken": "^9.0.2",
79+
"@types/bcryptjs": "^2.4.2",
7980
"ts-node": "^10.9.1",
8081
"typescript": "^5.1.3",
8182
"semantic-release": "^21.0.5",
@@ -110,7 +111,8 @@
110111
"@trpc/server": "^10.32.0",
111112
"@trpc/client": "^10.32.0",
112113
"jsonwebtoken": "^9.0.0",
113-
"zod": "^3.21.4"
114+
"zod": "^3.21.4",
115+
"bcryptjs": "^2.4.3"
114116
},
115117
"scripts": {
116118
"clean": "rm -rf ./lib",

‎src/node/api/db.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import { Hex, keccak256 } from 'viem';
21
import { z } from 'zod';
2+
import { hash } from 'bcryptjs';
33
import { Storage } from '../../storage/index.js';
44

5+
export { compare as comparePassword } from 'bcryptjs';
6+
57
/**
68
* Interface defining the properties of a User object stored in storage.
79
*/
@@ -39,17 +41,13 @@ export interface UsersDbOptions {
3941
storage: Storage;
4042
/** Prefix used for the storage key to avoid potential key collisions */
4143
prefix: string;
42-
/** Salt used for hashing passwords */
43-
salt: string;
4444
}
4545

4646
export class UsersDb {
4747
/** Storage instance for persisting the state of the API server */
4848
storage: Storage;
4949
/** Specific key prefix for the storage key to avoid potential key collisions */
5050
prefix: string;
51-
/** Salt used for hashing passwords */
52-
salt: string;
5351

5452
/**
5553
* Creates an instance of UsersDb.
@@ -59,26 +57,24 @@ export class UsersDb {
5957
* @memberof NodeApiServer
6058
*/
6159
constructor(options: UsersDbOptions) {
62-
const { storage, prefix, salt } = options;
60+
const { storage, prefix } = options;
6361

6462
// TODO Validate NodeApiServerOptions
6563

6664
this.prefix = `${prefix}_api_users_`;
6765
this.storage = storage;
68-
this.salt = salt;
6966
}
7067

7168
/**
7269
* Hashes the given password with the given salt.
7370
*
7471
* @static
7572
* @param {string} password The password to be hashed
76-
* @param {string} salt The salt to be used for hashing
7773
* @returns {string} The hashed password
7874
* @memberof UsersDb
7975
*/
80-
static hashPassword(password: string, salt: string): string {
81-
return keccak256(`${password}${salt}` as Hex);
76+
static async hashPassword(password: string): Promise<string> {
77+
return await hash(password, 10);
8278
}
8379

8480
/**
@@ -132,7 +128,7 @@ export class UsersDb {
132128
// Save the user into the storage
133129
await this.storage.set<User>(this.loginKey(login), {
134130
login,
135-
hashedPassword: UsersDb.hashPassword(password, this.salt),
131+
hashedPassword: await UsersDb.hashPassword(password),
136132
isAdmin,
137133
});
138134
}

‎src/node/api/router/user.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { TRPCError } from '@trpc/server';
2-
import { User, UserInputSchema, UsersDb } from '../db.js';
2+
import { User, UserInputSchema, comparePassword } from '../db.js';
33
import {
44
APIContext,
55
router,
@@ -56,9 +56,12 @@ export const userRouter = router({
5656
});
5757
}
5858

59-
if (
60-
user.hashedPassword !== UsersDb.hashPassword(password, server.users.salt)
61-
) {
59+
const isValidPassword = await comparePassword(
60+
password,
61+
user.hashedPassword,
62+
);
63+
64+
if (!isValidPassword) {
6265
throw new TRPCError({
6366
code: 'UNAUTHORIZED',
6467
message: 'Invalid login or password',

‎src/node/api/server.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,6 @@ export interface NodeApiServerOptions {
123123
*/
124124
port: number;
125125

126-
/**
127-
* A salt string used for hashing passwords. This adds an extra layer of security by
128-
* making it much harder for someone to reverse-engineer the original password from the hash.
129-
*/
130-
salt: string;
131-
132126
/**
133127
* A secret string used by the application for various purposes, often for signing and verifying tokens.
134128
*/
@@ -173,8 +167,7 @@ export class NodeApiServer {
173167
* @memberof NodeApiServer
174168
*/
175169
constructor(options: NodeApiServerOptions) {
176-
const { storage, prefix, port, salt, secret, ownerAccount, expire } =
177-
options;
170+
const { storage, prefix, port, secret, ownerAccount, expire } = options;
178171

179172
// TODO Validate NodeApiServerOptions
180173

@@ -184,7 +177,7 @@ export class NodeApiServer {
184177
this.expire = expire ?? '1h';
185178

186179
/** Initialize the UsersDb instance with the provided options */
187-
this.users = new UsersDb({ storage, prefix, salt });
180+
this.users = new UsersDb({ storage, prefix });
188181
}
189182

190183
/**

‎test/node.api.nodeApiServer.spec.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ describe('NodeApiServer', () => {
4747
options = {
4848
storage: await createInitializer()(),
4949
prefix: 'test',
50-
salt: 'salt',
5150
port: 3456,
5251
secret: 'secret',
5352
ownerAccount: owner.address,

‎yarn.lock

Lines changed: 12 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1661,6 +1661,11 @@
16611661
"@tufjs/canonical-json" "1.0.0"
16621662
minimatch "^9.0.0"
16631663

1664+
"@types/bcryptjs@^2.4.2":
1665+
version "2.4.2"
1666+
resolved "https://registry.yarnpkg.com/@types/bcryptjs/-/bcryptjs-2.4.2.tgz#e3530eac9dd136bfdfb0e43df2c4c5ce1f77dfae"
1667+
integrity sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ==
1668+
16641669
"@types/chai-subset@^1.3.3":
16651670
version "1.3.3"
16661671
resolved "https://registry.yarnpkg.com/@types/chai-subset/-/chai-subset-1.3.3.tgz#97893814e92abd2c534de422cb377e0e0bdaac94"
@@ -2818,6 +2823,11 @@ bcrypt-pbkdf@^1.0.0:
28182823
dependencies:
28192824
tweetnacl "^0.14.3"
28202825

2826+
bcryptjs@^2.4.3:
2827+
version "2.4.3"
2828+
resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb"
2829+
integrity sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==
2830+
28212831
before-after-hook@^2.2.0:
28222832
version "2.2.3"
28232833
resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c"
@@ -3764,7 +3774,7 @@ debug@^3.1.0:
37643774
dependencies:
37653775
ms "^2.1.1"
37663776

3767-
debuglog@*, debuglog@^1.0.1:
3777+
debuglog@^1.0.1:
37683778
version "1.0.1"
37693779
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
37703780
integrity sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw==
@@ -5322,7 +5332,7 @@ import-lazy@^2.1.0:
53225332
resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43"
53235333
integrity sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==
53245334

5325-
imurmurhash@*, imurmurhash@^0.1.4:
5335+
imurmurhash@^0.1.4:
53265336
version "0.1.4"
53275337
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
53285338
integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
@@ -6666,11 +6676,6 @@ lodash-es@^4.17.21:
66666676
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
66676677
integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
66686678

6669-
lodash._baseindexof@*:
6670-
version "3.1.0"
6671-
resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c"
6672-
integrity sha512-bSYo8Pc/f0qAkr8fPJydpJjtrHiSynYfYBjtANIgXv5xEf1WlTC63dIDlgu0s9dmTvzRu1+JJTxcIAHe+sH0FQ==
6673-
66746679
lodash._baseuniq@~4.6.0:
66756680
version "4.6.0"
66766681
resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8"
@@ -6679,33 +6684,11 @@ lodash._baseuniq@~4.6.0:
66796684
lodash._createset "~4.0.0"
66806685
lodash._root "~3.0.0"
66816686

6682-
lodash._bindcallback@*:
6683-
version "3.0.1"
6684-
resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e"
6685-
integrity sha512-2wlI0JRAGX8WEf4Gm1p/mv/SZ+jLijpj0jyaE/AXeuQphzCgD8ZQW4oSpoN8JAopujOFGU3KMuq7qfHBWlGpjQ==
6686-
6687-
lodash._cacheindexof@*:
6688-
version "3.0.2"
6689-
resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92"
6690-
integrity sha512-S8dUjWr7SUT/X6TBIQ/OYoCHo1Stu1ZRy6uMUSKqzFnZp5G5RyQizSm6kvxD2Ewyy6AVfMg4AToeZzKfF99T5w==
6691-
6692-
lodash._createcache@*:
6693-
version "3.1.2"
6694-
resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093"
6695-
integrity sha512-ev5SP+iFpZOugyab/DEUQxUeZP5qyciVTlgQ1f4Vlw7VUcCD8fVnyIqVUEIaoFH9zjAqdgi69KiofzvVmda/ZQ==
6696-
dependencies:
6697-
lodash._getnative "^3.0.0"
6698-
66996687
lodash._createset@~4.0.0:
67006688
version "4.0.3"
67016689
resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26"
67026690
integrity sha512-GTkC6YMprrJZCYU3zcqZj+jkXkrXzq3IPBcF/fIPpNEAB4hZEtXU8zp/RwKOvZl43NUmwDbyRk3+ZTbeRdEBXA==
67036691

6704-
lodash._getnative@*, lodash._getnative@^3.0.0:
6705-
version "3.9.1"
6706-
resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
6707-
integrity sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA==
6708-
67096692
lodash._root@~3.0.0:
67106693
version "3.0.1"
67116694
resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692"
@@ -6766,11 +6749,6 @@ lodash.mergewith@^4.6.2:
67666749
resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55"
67676750
integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==
67686751

6769-
lodash.restparam@*:
6770-
version "3.6.1"
6771-
resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805"
6772-
integrity sha512-L4/arjjuq4noiUJpt3yS6KIKDtJwNe2fIYgMqyYYKoeIfV1iEqvPwhCx23o+R9dzouGihDAPN1dTIRWa7zk8tw==
6773-
67746752
lodash.snakecase@^4.1.1:
67756753
version "4.1.1"
67766754
resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d"

0 commit comments

Comments
 (0)