Skip to content

Commit 7160713

Browse files
committed
feat: implement admin authentication and registration system
- Added new Admin model in Prisma schema - Introduced admin registration, login, and status endpoints - Implemented secure password hashing and verification - Added new error codes for admin-related operations - Updated auth routes and contract library - Removed hardcoded superadmin credentials from environment configuration
1 parent dd4f8da commit 7160713

39 files changed

+723
-33
lines changed

.env.sample

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,6 @@ LIMITED_USER_REMARKS=["🔴 Subscription limited","Contact support"]
4141
### RAW DOMAIN, WITHOUT HTTP/HTTPS, DO NOT PLACE / to end of domain ###
4242
SUB_PUBLIC_DOMAIN=example.com
4343

44-
45-
### SUPERADMIN ###
46-
### CHANGE DEFAULT VALUES ###
47-
SUPERADMIN_USERNAME=change_me
48-
SUPERADMIN_PASSWORD=change_me
49-
5044
### SWAGGER ###
5145
SWAGGER_PATH=/docs
5246
SCALAR_PATH=/scalar

libs/contract/api/controllers/auth.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@ export const AUTH_CONTROLLER = 'auth' as const;
22

33
export const AUTH_ROUTES = {
44
LOGIN: 'login',
5+
REGISTER: 'register',
6+
GET_STATUS: 'status',
57
} as const;

libs/contract/api/routes.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ export const METRICS_ROOT = '/metrics' as const;
66
export const REST_API = {
77
AUTH: {
88
LOGIN: `${ROOT}/${CONTROLLERS.AUTH_CONTROLLER}/${CONTROLLERS.AUTH_ROUTES.LOGIN}`,
9+
REGISTER: `${ROOT}/${CONTROLLERS.AUTH_CONTROLLER}/${CONTROLLERS.AUTH_ROUTES.REGISTER}`,
10+
GET_STATUS: `${ROOT}/${CONTROLLERS.AUTH_CONTROLLER}/${CONTROLLERS.AUTH_ROUTES.GET_STATUS}`,
911
},
1012
API_TOKENS: {
1113
CREATE: `${ROOT}/${CONTROLLERS.API_TOKENS_CONTROLLER}/${CONTROLLERS.API_TOKENS_ROUTES.CREATE}`,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { z } from 'zod';
2+
3+
import { REST_API } from '../../api';
4+
export namespace GetStatusCommand {
5+
export const url = REST_API.AUTH.GET_STATUS;
6+
export const TSQ_url = url;
7+
8+
export const ResponseSchema = z.object({
9+
response: z.object({
10+
isLoginAllowed: z.boolean(),
11+
isRegisterAllowed: z.boolean(),
12+
}),
13+
});
14+
15+
export type Response = z.infer<typeof ResponseSchema>;
16+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
export * from './login.command';
2+
export * from './register.command';
3+
export * from './get-status.command';
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { z } from 'zod';
2+
3+
import { REST_API } from '../../api';
4+
export namespace RegisterCommand {
5+
export const url = REST_API.AUTH.REGISTER;
6+
export const TSQ_url = url;
7+
8+
export const RequestSchema = z.object({
9+
username: z.string(),
10+
password: z
11+
.string()
12+
.min(24, 'Password must contain at least 24 characters')
13+
.regex(
14+
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[A-Za-z\d]/,
15+
'Password must contain uppercase and lowercase letters and numbers',
16+
),
17+
});
18+
19+
export type Request = z.infer<typeof RequestSchema>;
20+
21+
export const ResponseSchema = z.object({
22+
response: z.object({
23+
accessToken: z.string(),
24+
}),
25+
});
26+
27+
export type Response = z.infer<typeof ResponseSchema>;
28+
}

libs/contract/constants/errors/errors.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,4 +321,16 @@ export const ERRORS = {
321321
message: 'Update exceeded traffic users error',
322322
httpCode: 500,
323323
},
324+
ADMIN_NOT_FOUND: {
325+
code: 'A065',
326+
message: 'Admin not found',
327+
httpCode: 404,
328+
},
329+
CREATE_ADMIN_ERROR: {
330+
code: 'A066',
331+
message: 'Create admin error',
332+
httpCode: 500,
333+
},
334+
GET_AUTH_STATUS_ERROR: { code: 'A067', message: 'Get auth status error', httpCode: 500 },
335+
FORBIDDEN: { code: 'A068', message: 'Forbidden', httpCode: 403 },
324336
} as const;

libs/contract/constants/roles/role.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ export const ROLE = {
55

66
export type TRole = typeof ROLE;
77
export type TRolesKeys = (typeof ROLE)[keyof typeof ROLE];
8+
export type TRoleTypes = [keyof typeof ROLE][number];

libs/contract/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@remnawave/backend-contract",
3-
"version": "0.2.0",
3+
"version": "0.2.3",
44
"public": true,
55
"license": "AGPL-3.0-only",
66
"description": "A contract library for Remnawave Backend. It can be used in backend and frontend.",

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@
9898
},
9999
"devDependencies": {
100100
"@compodoc/compodoc": "^1.1.26",
101-
"@nestjs/cli": "11.0.4",
101+
"@nestjs/cli": "11.0.5",
102102
"@nestjs/schematics": "11.0.1",
103103
"@types/bcrypt": "^5.0.2",
104104
"@types/compression": "^1.7.5",

0 commit comments

Comments
 (0)