Skip to content

Commit 3e4af25

Browse files
committed
feat: 🎸 Added final UserdDB implementation
1 parent 8eafa93 commit 3e4af25

File tree

1 file changed

+58
-19
lines changed

1 file changed

+58
-19
lines changed

‎src/node/api/db.ts

Lines changed: 58 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,79 +3,100 @@ import { z } from 'zod';
33
import { Storage } from '../../storage/index.js';
44

55
/**
6-
* User object stored in the storage
6+
* Interface defining the properties of a User object stored in storage.
77
*/
88
export interface User {
9+
/** The username of the user */
910
login: string;
11+
/** The hashed password of the user */
1012
hashedPassword: string;
13+
/** The optional JSON Web Token of the user */
1114
jwt?: string;
1215
}
1316

1417
/**
15-
* User creation API input validation schema
18+
* Validation schema for user creation API input.
19+
* It validates that the input contains a nonempty `login` and `password`.
1620
*/
1721
export const UserInputSchema = z.object({
18-
login: z.string(),
19-
password: z.string(),
22+
login: z.string().nonempty(),
23+
password: z.string().nonempty(),
2024
});
2125

2226
/**
23-
* Users database initialization options type
27+
* Type definition for User registration input,
28+
* inferred from UserInputSchema.
29+
*/
30+
export type UserInputType = z.infer<typeof UserInputSchema>;
31+
32+
/**
33+
* Interface defining the properties of UsersDb initialization options.
2434
*/
2535
export interface UsersDbOptions {
2636
/** Instance of storage used for persisting the state of the API server */
2737
storage: Storage;
2838
/** Prefix used for the storage key to avoid potential key collisions */
2939
prefix: string;
30-
/** Passwords hashing salt */
40+
/** Salt used for hashing passwords */
3141
salt: string;
3242
}
3343

3444
export class UsersDb {
3545
/** Storage instance for persisting the state of the API server */
36-
private storage: Storage;
46+
storage: Storage;
3747
/** Specific key prefix for the storage key to avoid potential key collisions */
38-
private prefix: string;
39-
/** Passwords hashing salt */
48+
prefix: string;
49+
/** Salt used for hashing passwords */
4050
salt: string;
4151

4252
/**
4353
* Creates an instance of UsersDb.
54+
* Initializes an instance of UsersDb with given options.
4455
*
4556
* @param {UsersDbOptions} options
4657
* @memberof NodeApiServer
4758
*/
4859
constructor(options: UsersDbOptions) {
4960
const { storage, prefix, salt } = options;
5061

51-
// @todo Validate NodeApiServerOptions
62+
// TODO Validate NodeApiServerOptions
5263

5364
this.prefix = `${prefix}_api_users_`;
5465
this.storage = storage;
5566
this.salt = salt;
5667
}
5768

69+
/**
70+
* Hashes the given password with the given salt.
71+
*
72+
* @static
73+
* @param {string} password The password to be hashed
74+
* @param {string} salt The salt to be used for hashing
75+
* @returns {string} The hashed password
76+
* @memberof UsersDb
77+
*/
5878
static hashPassword(password: string, salt: string): string {
5979
return keccak256(`${password}${salt}` as Hex);
6080
}
6181

6282
/**
63-
* Returns prefixed login key
83+
* Generates a prefixed login key
6484
*
6585
* @private
66-
* @param {string} login
67-
* @returns {string}
86+
* @param {string} login The login for which the key is generated
87+
* @returns {string} The prefixed login key
6888
* @memberof UsersDb
6989
*/
7090
private loginKey(login: string): string {
7191
return `${this.prefix}${login}`;
7292
}
7393

7494
/**
75-
* Returns the user from storage
95+
* Retrieves the user with the given login from storage.
7696
*
77-
* @param {string} login
78-
* @returns {Promise<User>}
97+
* @param {string} login The login of the user to be retrieved
98+
* @returns {Promise<User>} The User object associated with the given login
99+
* @throws Will throw an error if the user is not found
79100
* @memberof UsersDb
80101
*/
81102
async get(login: string): Promise<User> {
@@ -89,30 +110,48 @@ export class UsersDb {
89110
}
90111

91112
/**
92-
* Creates a new user record in the storage
113+
* Adds a new user to the storage.
93114
*
94-
* @param {string} login
95-
* @param {string} password
115+
* @param {string} login The login of the user to be added
116+
* @param {string} password The password of the user to be added
96117
* @returns {Promise<void>}
118+
* @throws Will throw an error if a user with the same login already exists
97119
* @memberof UsersDb
98120
*/
99121
async add(login: string, password: string): Promise<void> {
100122
const knownUser = await this.storage.get<User>(this.loginKey(login));
101123

124+
// Check if the user already exists
102125
if (knownUser) {
103126
throw new Error(`User ${login} already exists`);
104127
}
105128

129+
// Save the user into the storage
106130
await this.storage.set<User>(this.loginKey(login), {
107131
login,
108132
hashedPassword: UsersDb.hashPassword(password, this.salt),
109133
});
110134
}
111135

136+
/**
137+
* Updates the record of the user in the storage
138+
*
139+
* @param {User} user The user object
140+
* @returns {Promise<void>}
141+
* @memberof UsersDb
142+
*/
112143
async set(user: User): Promise<void> {
113144
await this.storage.set<User>(this.loginKey(user.login), user);
114145
}
115146

147+
/**
148+
* Deletes the user from storage
149+
*
150+
* @param {string} login The user login name
151+
* @returns {Promise<void>}
152+
* @throws Will throw an error if not possible to delete the user
153+
* @memberof UsersDb
154+
*/
116155
async delete(login: string): Promise<void> {
117156
const deleted = await this.storage.delete(this.loginKey(login));
118157

0 commit comments

Comments
 (0)