stackkit 0.2.8 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/bin/stackkit.js +8 -5
- package/dist/cli/add.js +4 -9
- package/dist/cli/create.js +4 -9
- package/dist/cli/doctor.js +11 -32
- package/dist/lib/constants.js +3 -4
- package/dist/lib/conversion/js-conversion.js +20 -16
- package/dist/lib/discovery/installed-detection.js +28 -38
- package/dist/lib/discovery/module-discovery.d.ts +0 -15
- package/dist/lib/discovery/module-discovery.js +15 -50
- package/dist/lib/framework/framework-utils.d.ts +4 -5
- package/dist/lib/framework/framework-utils.js +38 -49
- package/dist/lib/fs/files.js +1 -1
- package/dist/lib/generation/code-generator.d.ts +13 -19
- package/dist/lib/generation/code-generator.js +159 -175
- package/dist/lib/generation/generator-utils.js +3 -15
- package/dist/lib/project/detect.js +11 -19
- package/dist/lib/utils/fs-helpers.d.ts +1 -1
- package/modules/auth/authjs/generator.json +16 -16
- package/modules/auth/better-auth/files/express/middlewares/authorize.ts +178 -40
- package/modules/auth/better-auth/files/express/modules/auth/auth.controller.ts +264 -0
- package/modules/auth/better-auth/files/express/modules/auth/auth.route.ts +27 -0
- package/modules/auth/better-auth/files/express/modules/auth/auth.service.ts +537 -0
- package/modules/auth/better-auth/files/express/modules/auth/auth.type.ts +33 -0
- package/modules/auth/better-auth/files/express/templates/google-redirect.ejs +91 -0
- package/modules/auth/better-auth/files/express/templates/otp.ejs +87 -0
- package/modules/auth/better-auth/files/express/types/express.d.ts +6 -8
- package/modules/auth/better-auth/files/express/utils/cookie.ts +19 -0
- package/modules/auth/better-auth/files/express/utils/jwt.ts +34 -0
- package/modules/auth/better-auth/files/express/utils/token.ts +66 -0
- package/modules/auth/better-auth/files/nextjs/api/auth/[...all]/route.ts +1 -1
- package/modules/auth/better-auth/files/nextjs/lib/auth/auth-guards.ts +11 -1
- package/modules/auth/better-auth/files/nextjs/templates/email-otp.tsx +74 -0
- package/modules/auth/better-auth/files/shared/config/env.ts +117 -0
- package/modules/auth/better-auth/files/shared/lib/auth-client.ts +1 -1
- package/modules/auth/better-auth/files/shared/lib/auth.ts +167 -79
- package/modules/auth/better-auth/files/shared/mongoose/auth/constants.ts +11 -0
- package/modules/auth/better-auth/files/shared/mongoose/auth/helper.ts +51 -0
- package/modules/auth/better-auth/files/shared/prisma/schema.prisma +22 -11
- package/modules/auth/better-auth/files/shared/utils/email.ts +70 -0
- package/modules/auth/better-auth/generator.json +162 -80
- package/modules/database/mongoose/files/lib/mongoose.ts +28 -3
- package/modules/database/mongoose/generator.json +18 -18
- package/modules/database/prisma/generator.json +44 -44
- package/package.json +2 -2
- package/templates/express/env.example +3 -2
- package/templates/express/eslint.config.mjs +7 -0
- package/templates/express/node_modules/.bin/acorn +17 -0
- package/templates/express/node_modules/.bin/eslint +17 -0
- package/templates/express/node_modules/.bin/tsc +17 -0
- package/templates/express/node_modules/.bin/tsserver +17 -0
- package/templates/express/node_modules/.bin/tsx +17 -0
- package/templates/express/package.json +12 -6
- package/templates/express/src/app.ts +15 -7
- package/templates/express/src/config/cors.ts +8 -7
- package/templates/express/src/config/env.ts +28 -5
- package/templates/express/src/config/logger.ts +2 -2
- package/templates/express/src/config/rate-limit.ts +2 -2
- package/templates/express/src/modules/health/health.controller.ts +13 -11
- package/templates/express/src/routes/index.ts +1 -6
- package/templates/express/src/server.ts +12 -12
- package/templates/express/src/shared/errors/app-error.ts +16 -0
- package/templates/express/src/shared/middlewares/error.middleware.ts +154 -12
- package/templates/express/src/shared/middlewares/not-found.middleware.ts +2 -1
- package/templates/express/src/shared/utils/catch-async.ts +11 -0
- package/templates/express/src/shared/utils/pagination.ts +6 -1
- package/templates/express/src/shared/utils/send-response.ts +25 -0
- package/templates/nextjs/lib/env.ts +19 -8
- package/modules/auth/better-auth/files/shared/lib/email/email-service.ts +0 -33
- package/modules/auth/better-auth/files/shared/lib/email/email-templates.ts +0 -89
- package/templates/express/eslint.config.cjs +0 -42
- package/templates/express/src/config/helmet.ts +0 -5
- package/templates/express/src/modules/health/health.service.ts +0 -6
- package/templates/express/src/shared/errors/error-codes.ts +0 -9
- package/templates/express/src/shared/logger/logger.ts +0 -20
- package/templates/express/src/shared/utils/async-handler.ts +0 -9
- package/templates/express/src/shared/utils/response.ts +0 -9
|
@@ -64,7 +64,7 @@ async function mergeModuleIntoGeneratorConfig(config, modulePath) {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
catch {
|
|
67
|
-
|
|
67
|
+
return config;
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
return config;
|
|
@@ -74,7 +74,6 @@ async function mergeGeneratorIntoModuleMetadata(metadata, modulePath) {
|
|
|
74
74
|
if (await fs.pathExists(generatorPath)) {
|
|
75
75
|
try {
|
|
76
76
|
const generator = await fs.readJson(generatorPath);
|
|
77
|
-
// Process add-env operations to extract envVars
|
|
78
77
|
if (generator.operations && Array.isArray(generator.operations)) {
|
|
79
78
|
for (const operation of generator.operations) {
|
|
80
79
|
if (operation.type === "add-env" && operation.envVars) {
|
|
@@ -90,11 +89,6 @@ async function mergeGeneratorIntoModuleMetadata(metadata, modulePath) {
|
|
|
90
89
|
});
|
|
91
90
|
}
|
|
92
91
|
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
// Collect dependencies/devDependencies from add-dependency operations
|
|
96
|
-
if (generator.operations && Array.isArray(generator.operations)) {
|
|
97
|
-
for (const operation of generator.operations) {
|
|
98
92
|
if (operation.type === "add-dependency") {
|
|
99
93
|
if (operation.dependencies) {
|
|
100
94
|
metadata.dependencies = {
|
|
@@ -117,7 +111,7 @@ async function mergeGeneratorIntoModuleMetadata(metadata, modulePath) {
|
|
|
117
111
|
}
|
|
118
112
|
}
|
|
119
113
|
catch {
|
|
120
|
-
|
|
114
|
+
return metadata;
|
|
121
115
|
}
|
|
122
116
|
}
|
|
123
117
|
return metadata;
|
|
@@ -129,13 +123,7 @@ function locateOperationSource(generatorType, generatorName, sourceRel) {
|
|
|
129
123
|
const moduleBasePath = generatorType === "framework"
|
|
130
124
|
? path.join(templatesPath, generatorName)
|
|
131
125
|
: path.join(modulesPath, generatorType, generatorName);
|
|
132
|
-
|
|
133
|
-
try {
|
|
134
|
-
return sourcePath;
|
|
135
|
-
}
|
|
136
|
-
catch {
|
|
137
|
-
return null;
|
|
138
|
-
}
|
|
126
|
+
return path.join(moduleBasePath, "files", sourceRel);
|
|
139
127
|
}
|
|
140
128
|
exports.default = {
|
|
141
129
|
mergeModuleIntoGeneratorConfig,
|
|
@@ -8,16 +8,15 @@ exports.getRouterBasePath = getRouterBasePath;
|
|
|
8
8
|
exports.getLibPath = getLibPath;
|
|
9
9
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
10
10
|
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const constants_1 = require("../constants");
|
|
11
12
|
const installed_detection_1 = require("../discovery/installed-detection");
|
|
12
13
|
const package_root_1 = require("../utils/package-root");
|
|
13
14
|
async function detectProjectInfo(targetDir) {
|
|
14
|
-
const packageJsonPath = path_1.default.join(targetDir,
|
|
15
|
+
const packageJsonPath = path_1.default.join(targetDir, constants_1.FILE_NAMES.PACKAGE_JSON);
|
|
15
16
|
if (!(await fs_extra_1.default.pathExists(packageJsonPath))) {
|
|
16
|
-
throw new Error(
|
|
17
|
+
throw new Error(constants_1.ERROR_MESSAGES.NO_PACKAGE_JSON);
|
|
17
18
|
}
|
|
18
19
|
const packageJson = await fs_extra_1.default.readJSON(packageJsonPath);
|
|
19
|
-
// Detect framework by matching available templates' characteristic files
|
|
20
|
-
// Framework is dynamic and driven by templates; keep as string for discovery
|
|
21
20
|
let framework = "unknown";
|
|
22
21
|
try {
|
|
23
22
|
const templatesDir = path_1.default.join((0, package_root_1.getPackageRoot)(), "templates");
|
|
@@ -41,19 +40,17 @@ async function detectProjectInfo(targetDir) {
|
|
|
41
40
|
bestMatch = { name: d, score };
|
|
42
41
|
}
|
|
43
42
|
catch {
|
|
44
|
-
|
|
43
|
+
continue;
|
|
45
44
|
}
|
|
46
45
|
}
|
|
47
46
|
if (bestMatch && bestMatch.score > 0) {
|
|
48
|
-
// Use the template folder name as the framework identifier
|
|
49
47
|
framework = bestMatch.name;
|
|
50
48
|
}
|
|
51
49
|
}
|
|
52
50
|
}
|
|
53
51
|
catch {
|
|
54
|
-
|
|
52
|
+
framework = "unknown";
|
|
55
53
|
}
|
|
56
|
-
// Fallback: simple dependency-based detection
|
|
57
54
|
if (framework === "unknown") {
|
|
58
55
|
const isNextJs = packageJson.dependencies?.next || packageJson.devDependencies?.next;
|
|
59
56
|
const isExpress = packageJson.dependencies?.express || packageJson.devDependencies?.express;
|
|
@@ -71,7 +68,6 @@ async function detectProjectInfo(targetDir) {
|
|
|
71
68
|
if (framework === "unknown") {
|
|
72
69
|
throw new Error("Unsupported project type or unable to detect framework from templates.");
|
|
73
70
|
}
|
|
74
|
-
// Detect router type (only for Next.js)
|
|
75
71
|
let router = "unknown";
|
|
76
72
|
if (framework === "nextjs") {
|
|
77
73
|
const appDirExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, "app"));
|
|
@@ -79,14 +75,13 @@ async function detectProjectInfo(targetDir) {
|
|
|
79
75
|
const srcAppDirExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, "src", "app"));
|
|
80
76
|
const srcPagesDirExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, "src", "pages"));
|
|
81
77
|
if (appDirExists || srcAppDirExists) {
|
|
82
|
-
router =
|
|
78
|
+
router = constants_1.ROUTER_TYPES.APP;
|
|
83
79
|
}
|
|
84
80
|
else if (pagesDirExists || srcPagesDirExists) {
|
|
85
|
-
router =
|
|
81
|
+
router = constants_1.ROUTER_TYPES.PAGES;
|
|
86
82
|
}
|
|
87
83
|
}
|
|
88
|
-
|
|
89
|
-
const tsconfigExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, "tsconfig.json"));
|
|
84
|
+
const tsconfigExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, constants_1.FILE_NAMES.TSCONFIG_JSON));
|
|
90
85
|
const jsconfigExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, "jsconfig.json"));
|
|
91
86
|
let language;
|
|
92
87
|
if (tsconfigExists) {
|
|
@@ -98,10 +93,9 @@ async function detectProjectInfo(targetDir) {
|
|
|
98
93
|
else {
|
|
99
94
|
language = "ts";
|
|
100
95
|
}
|
|
101
|
-
|
|
102
|
-
const
|
|
103
|
-
const
|
|
104
|
-
const bunLockExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, "bun.lockb"));
|
|
96
|
+
const yarnLockExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, constants_1.LOCK_FILES.yarn));
|
|
97
|
+
const pnpmLockExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, constants_1.LOCK_FILES.pnpm));
|
|
98
|
+
const bunLockExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, constants_1.LOCK_FILES.bun));
|
|
105
99
|
let packageManager = "pnpm";
|
|
106
100
|
if (pnpmLockExists) {
|
|
107
101
|
packageManager = "pnpm";
|
|
@@ -112,8 +106,6 @@ async function detectProjectInfo(targetDir) {
|
|
|
112
106
|
else if (bunLockExists) {
|
|
113
107
|
packageManager = "bun";
|
|
114
108
|
}
|
|
115
|
-
// Detect installed modules by comparing project dependencies against
|
|
116
|
-
// declared dependencies in `modules/*/generator.json` and `module.json`.
|
|
117
109
|
const detectedAuth = await (0, installed_detection_1.detectAuthModules)(packageJson);
|
|
118
110
|
const detectedDbs = await (0, installed_detection_1.detectDatabaseModules)(packageJson);
|
|
119
111
|
const hasAuth = detectedAuth.length > 0;
|
|
@@ -7,6 +7,6 @@ export declare function writeFile(filePath: string, content: string): Promise<vo
|
|
|
7
7
|
export declare function copyDir(source: string, destination: string, options?: CopyFilterFunction): Promise<void>;
|
|
8
8
|
export declare function readDir(dirPath: string): Promise<string[]>;
|
|
9
9
|
export declare function isDirectory(dirPath: string): Promise<boolean>;
|
|
10
|
-
export declare function findFilesInDir(dirPath: string, predicate: (
|
|
10
|
+
export declare function findFilesInDir(dirPath: string, predicate: (fileName: string) => boolean): Promise<string[]>;
|
|
11
11
|
export declare function getEnvFilePath(projectRoot: string): Promise<string | null>;
|
|
12
12
|
export {};
|
|
@@ -3,11 +3,6 @@
|
|
|
3
3
|
"type": "auth",
|
|
4
4
|
"priority": 10,
|
|
5
5
|
"operations": [
|
|
6
|
-
{
|
|
7
|
-
"type": "create-file",
|
|
8
|
-
"source": "shared/lib/auth.ts",
|
|
9
|
-
"destination": "server/auth/auth.ts"
|
|
10
|
-
},
|
|
11
6
|
{
|
|
12
7
|
"type": "create-file",
|
|
13
8
|
"source": "nextjs/api/auth/[...nextauth]/route.ts",
|
|
@@ -18,6 +13,11 @@
|
|
|
18
13
|
"source": "nextjs/proxy.ts",
|
|
19
14
|
"destination": "proxy.ts"
|
|
20
15
|
},
|
|
16
|
+
{
|
|
17
|
+
"type": "create-file",
|
|
18
|
+
"source": "shared/lib/auth.ts",
|
|
19
|
+
"destination": "server/auth/auth.ts"
|
|
20
|
+
},
|
|
21
21
|
{
|
|
22
22
|
"type": "patch-file",
|
|
23
23
|
"destination": "prisma/schema.prisma",
|
|
@@ -36,6 +36,17 @@
|
|
|
36
36
|
"@auth/prisma-adapter": "^2.11.1"
|
|
37
37
|
}
|
|
38
38
|
},
|
|
39
|
+
{
|
|
40
|
+
"type": "add-dependency",
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"bcryptjs": "^3.0.3",
|
|
43
|
+
"next-auth": "^5.0.0-beta.30",
|
|
44
|
+
"nodemailer": "^7.0.12"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/nodemailer": "^7.0.5"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
39
50
|
{
|
|
40
51
|
"type": "add-env",
|
|
41
52
|
"envVars": {
|
|
@@ -48,17 +59,6 @@
|
|
|
48
59
|
"EMAIL_PASS": "",
|
|
49
60
|
"EMAIL_FROM": "noreply@yourapp.com"
|
|
50
61
|
}
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
"type": "add-dependency",
|
|
54
|
-
"dependencies": {
|
|
55
|
-
"next-auth": "^5.0.0-beta.30",
|
|
56
|
-
"bcryptjs": "^3.0.3",
|
|
57
|
-
"nodemailer": "^7.0.12"
|
|
58
|
-
},
|
|
59
|
-
"devDependencies": {
|
|
60
|
-
"@types/nodemailer": "^7.0.5"
|
|
61
|
-
}
|
|
62
62
|
}
|
|
63
63
|
]
|
|
64
64
|
}
|
|
@@ -1,54 +1,192 @@
|
|
|
1
1
|
import { NextFunction, Request, Response } from "express";
|
|
2
|
-
import
|
|
2
|
+
import status from "http-status";
|
|
3
|
+
import { envVars } from "../../config/env";
|
|
4
|
+
import { AppError } from "../errors/app-error";
|
|
5
|
+
import { cookieUtils } from "../utils/cookie";
|
|
6
|
+
import { jwtUtils } from "../utils/jwt";
|
|
7
|
+
{{#if database == "prisma"}}
|
|
8
|
+
import { Role, UserStatus } from "@prisma/client";
|
|
9
|
+
import { prisma } from "../../database/prisma";
|
|
10
|
+
{{/if}}
|
|
11
|
+
{{#if database == "mongoose"}}
|
|
12
|
+
import { Role, UserStatus } from "../../modules/auth/auth.constants";
|
|
13
|
+
import { getAuthCollections } from "../../modules/auth/auth.helper";
|
|
14
|
+
{{/if}}
|
|
3
15
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
16
|
+
{{#if database == "prisma"}}
|
|
17
|
+
export const authorize = (...authRoles: Role[]) =>
|
|
18
|
+
{{/if}}
|
|
19
|
+
{{#if database == "mongoose"}}
|
|
20
|
+
type AuthRole = (typeof Role)[keyof typeof Role];
|
|
8
21
|
|
|
9
|
-
const authorize = (...
|
|
10
|
-
|
|
22
|
+
export const authorize = (...authRoles: AuthRole[]) =>
|
|
23
|
+
{{/if}}
|
|
24
|
+
async (req: Request, res: Response, next: NextFunction) => {
|
|
11
25
|
try {
|
|
12
|
-
//
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
message: "You are not authorized!",
|
|
21
|
-
});
|
|
26
|
+
//Session Token Verification
|
|
27
|
+
const sessionToken = cookieUtils.getCookie(
|
|
28
|
+
req,
|
|
29
|
+
"better-auth.session_token",
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
if (!sessionToken) {
|
|
33
|
+
throw new Error("Unauthorized access! No session token provided.");
|
|
22
34
|
}
|
|
23
35
|
|
|
24
|
-
if (
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
36
|
+
if (sessionToken) {
|
|
37
|
+
{{#if database == "prisma"}}
|
|
38
|
+
const sessionExists = await prisma.session.findFirst({
|
|
39
|
+
where: {
|
|
40
|
+
token: sessionToken,
|
|
41
|
+
expiresAt: {
|
|
42
|
+
gt: new Date(),
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
include: {
|
|
46
|
+
user: true,
|
|
47
|
+
},
|
|
28
48
|
});
|
|
49
|
+
{{/if}}
|
|
50
|
+
{{#if database == "mongoose"}}
|
|
51
|
+
const { sessions, users } = await getAuthCollections();
|
|
52
|
+
const sessionExists = await sessions.findOne({
|
|
53
|
+
token: sessionToken,
|
|
54
|
+
expiresAt: { $gt: new Date() },
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const user = sessionExists
|
|
58
|
+
? await users.findOne({
|
|
59
|
+
id: sessionExists.userId,
|
|
60
|
+
})
|
|
61
|
+
: null;
|
|
62
|
+
{{/if}}
|
|
63
|
+
|
|
64
|
+
{{#if database == "prisma"}}
|
|
65
|
+
if (sessionExists && sessionExists.user) {
|
|
66
|
+
const user = sessionExists.user;
|
|
67
|
+
{{/if}}
|
|
68
|
+
{{#if database == "mongoose"}}
|
|
69
|
+
if (sessionExists && user) {
|
|
70
|
+
{{/if}}
|
|
71
|
+
|
|
72
|
+
{{#if database == "prisma"}}
|
|
73
|
+
const now = new Date();
|
|
74
|
+
const expiresAt = new Date(sessionExists.expiresAt);
|
|
75
|
+
const createdAt = new Date(sessionExists.createdAt);
|
|
76
|
+
|
|
77
|
+
const sessionLifeTime = expiresAt.getTime() - createdAt.getTime();
|
|
78
|
+
const timeRemaining = expiresAt.getTime() - now.getTime();
|
|
79
|
+
const percentRemaining = (timeRemaining / sessionLifeTime) * 100;
|
|
80
|
+
|
|
81
|
+
if (percentRemaining < 20) {
|
|
82
|
+
res.setHeader("X-Session-Refresh", "true");
|
|
83
|
+
res.setHeader("X-Session-Expires-At", expiresAt.toISOString());
|
|
84
|
+
res.setHeader("X-Time-Remaining", timeRemaining.toString());
|
|
85
|
+
|
|
86
|
+
console.log("Session Expiring Soon!!");
|
|
87
|
+
}
|
|
88
|
+
{{/if}}
|
|
89
|
+
{{#if database == "mongoose"}}
|
|
90
|
+
if (sessionExists.expiresAt && sessionExists.createdAt) {
|
|
91
|
+
const now = new Date();
|
|
92
|
+
const expiresAt = new Date(sessionExists.expiresAt);
|
|
93
|
+
const createdAt = new Date(sessionExists.createdAt);
|
|
94
|
+
|
|
95
|
+
const sessionLifeTime = expiresAt.getTime() - createdAt.getTime();
|
|
96
|
+
const timeRemaining = expiresAt.getTime() - now.getTime();
|
|
97
|
+
const percentRemaining = (timeRemaining / sessionLifeTime) * 100;
|
|
98
|
+
|
|
99
|
+
if (percentRemaining < 20) {
|
|
100
|
+
res.setHeader("X-Session-Refresh", "true");
|
|
101
|
+
res.setHeader("X-Session-Expires-At", expiresAt.toISOString());
|
|
102
|
+
res.setHeader("X-Time-Remaining", timeRemaining.toString());
|
|
103
|
+
|
|
104
|
+
console.log("Session Expiring Soon!!");
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
{{/if}}
|
|
108
|
+
|
|
109
|
+
if (
|
|
110
|
+
user.status === UserStatus.BLOCKED ||
|
|
111
|
+
user.status === UserStatus.DELETED
|
|
112
|
+
) {
|
|
113
|
+
throw new AppError(
|
|
114
|
+
status.UNAUTHORIZED,
|
|
115
|
+
"Unauthorized access! User is not active.",
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (user.isDeleted) {
|
|
120
|
+
throw new AppError(
|
|
121
|
+
status.UNAUTHORIZED,
|
|
122
|
+
"Unauthorized access! User is deleted.",
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
{{#if database == "prisma"}}
|
|
127
|
+
if (authRoles.length > 0 && !authRoles.includes(user.role)) {
|
|
128
|
+
{{/if}}
|
|
129
|
+
{{#if database == "mongoose"}}
|
|
130
|
+
if (authRoles.length > 0 && !authRoles.includes(user.role as AuthRole)) {
|
|
131
|
+
{{/if}}
|
|
132
|
+
throw new AppError(
|
|
133
|
+
status.FORBIDDEN,
|
|
134
|
+
"Forbidden access! You do not have permission to access this resource.",
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
req.user = {
|
|
139
|
+
id: user.id,
|
|
140
|
+
name: user.name,
|
|
141
|
+
email: user.email,
|
|
142
|
+
role: user.role,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const accessToken = cookieUtils.getCookie(req, "accessToken");
|
|
147
|
+
|
|
148
|
+
if (!accessToken) {
|
|
149
|
+
throw new AppError(
|
|
150
|
+
status.UNAUTHORIZED,
|
|
151
|
+
"Unauthorized access! No access token provided.",
|
|
152
|
+
);
|
|
153
|
+
}
|
|
29
154
|
}
|
|
30
155
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
156
|
+
//Access Token Verification
|
|
157
|
+
const accessToken = cookieUtils.getCookie(req, "accessToken");
|
|
158
|
+
|
|
159
|
+
if (!accessToken) {
|
|
160
|
+
throw new AppError(
|
|
161
|
+
status.UNAUTHORIZED,
|
|
162
|
+
"Unauthorized access! No access token provided.",
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const verifiedToken = jwtUtils.verifyToken(
|
|
167
|
+
accessToken,
|
|
168
|
+
envVars.ACCESS_TOKEN_SECRET,
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
if (!verifiedToken.success) {
|
|
172
|
+
throw new AppError(
|
|
173
|
+
status.UNAUTHORIZED,
|
|
174
|
+
"Unauthorized access! Invalid access token.",
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (
|
|
179
|
+
authRoles.length > 0 &&
|
|
180
|
+
!authRoles.includes(verifiedToken.data!.role)
|
|
181
|
+
) {
|
|
182
|
+
throw new AppError(
|
|
183
|
+
status.FORBIDDEN,
|
|
184
|
+
"Forbidden access! You do not have permission to access this resource.",
|
|
185
|
+
);
|
|
45
186
|
}
|
|
46
187
|
|
|
47
188
|
next();
|
|
48
|
-
} catch (
|
|
49
|
-
next(
|
|
189
|
+
} catch (error: unknown) {
|
|
190
|
+
next(error);
|
|
50
191
|
}
|
|
51
|
-
};
|
|
52
192
|
};
|
|
53
|
-
|
|
54
|
-
export default authorize;
|