@skillstew/common 1.0.1 → 1.0.3

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.
@@ -0,0 +1,14 @@
1
+ export declare abstract class AppError extends Error {
2
+ readonly message: string;
3
+ readonly code: string;
4
+ readonly context?: Record<string, unknown> | undefined;
5
+ readonly name: string;
6
+ constructor(message: string, code: string, context?: Record<string, unknown> | undefined);
7
+ abstract toJSON(): object;
8
+ }
9
+ export declare abstract class DomainError extends AppError {
10
+ }
11
+ export declare abstract class InfrastructureError extends AppError {
12
+ }
13
+ export declare abstract class ApplicationError extends AppError {
14
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ApplicationError = exports.InfrastructureError = exports.DomainError = exports.AppError = void 0;
4
+ class AppError extends Error {
5
+ constructor(message, code, context) {
6
+ super(message);
7
+ this.message = message;
8
+ this.code = code;
9
+ this.context = context;
10
+ this.name = this.constructor.name;
11
+ Object.setPrototypeOf(this, new.target.prototype);
12
+ }
13
+ }
14
+ exports.AppError = AppError;
15
+ class DomainError extends AppError {
16
+ }
17
+ exports.DomainError = DomainError;
18
+ class InfrastructureError extends AppError {
19
+ }
20
+ exports.InfrastructureError = InfrastructureError;
21
+ class ApplicationError extends AppError {
22
+ }
23
+ exports.ApplicationError = ApplicationError;
@@ -0,0 +1,24 @@
1
+ import { InfrastructureError } from "./AppError";
2
+ import { JwtErrorCodes } from "./codes/JwtErrorCodes";
3
+ export declare class JwtError extends InfrastructureError {
4
+ constructor(code: keyof typeof JwtErrorCodes);
5
+ toJSON(): object;
6
+ }
7
+ export declare class EmailVerificationJwtVerifyError extends JwtError {
8
+ constructor();
9
+ }
10
+ export declare class RefreshTokenVerifyError extends JwtError {
11
+ constructor();
12
+ }
13
+ export declare class AccessTokenVerifyError extends JwtError {
14
+ constructor();
15
+ }
16
+ export declare class InvalidTokenError extends JwtError {
17
+ constructor();
18
+ }
19
+ export declare class InvalidTokenRoleError extends JwtError {
20
+ constructor();
21
+ }
22
+ export declare class TokenRoleMismatchError extends JwtError {
23
+ constructor();
24
+ }
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TokenRoleMismatchError = exports.InvalidTokenRoleError = exports.InvalidTokenError = exports.AccessTokenVerifyError = exports.RefreshTokenVerifyError = exports.EmailVerificationJwtVerifyError = exports.JwtError = void 0;
4
+ const AppError_1 = require("./AppError");
5
+ const JwtErrorCodes_1 = require("./codes/JwtErrorCodes");
6
+ class JwtError extends AppError_1.InfrastructureError {
7
+ constructor(code) {
8
+ super(JwtErrorCodes_1.JwtErrorCodes[code], code);
9
+ }
10
+ toJSON() {
11
+ return { error: this.name, message: this.message, code: this.code };
12
+ }
13
+ }
14
+ exports.JwtError = JwtError;
15
+ class EmailVerificationJwtVerifyError extends JwtError {
16
+ constructor() {
17
+ super("EMAIL_VERIFICATION_JWT_VERIFY_ERROR");
18
+ }
19
+ }
20
+ exports.EmailVerificationJwtVerifyError = EmailVerificationJwtVerifyError;
21
+ class RefreshTokenVerifyError extends JwtError {
22
+ constructor() {
23
+ super("REFRESH_TOKEN_VERIFY_ERROR");
24
+ }
25
+ }
26
+ exports.RefreshTokenVerifyError = RefreshTokenVerifyError;
27
+ class AccessTokenVerifyError extends JwtError {
28
+ constructor() {
29
+ super("ACCESS_TOKEN_VERIFY_ERROR");
30
+ }
31
+ }
32
+ exports.AccessTokenVerifyError = AccessTokenVerifyError;
33
+ class InvalidTokenError extends JwtError {
34
+ constructor() {
35
+ super("INVALID_TOKEN_ERROR");
36
+ }
37
+ }
38
+ exports.InvalidTokenError = InvalidTokenError;
39
+ class InvalidTokenRoleError extends JwtError {
40
+ constructor() {
41
+ super("INVALID_TOKEN_ROLE_ERROR");
42
+ }
43
+ }
44
+ exports.InvalidTokenRoleError = InvalidTokenRoleError;
45
+ class TokenRoleMismatchError extends JwtError {
46
+ constructor() {
47
+ super("TOKEN_ROLE_MISMATCH_ERROR");
48
+ }
49
+ }
50
+ exports.TokenRoleMismatchError = TokenRoleMismatchError;
@@ -0,0 +1,5 @@
1
+ import { ApplicationError } from "./AppError";
2
+ export declare class UnauthenticatedError extends ApplicationError {
3
+ constructor();
4
+ toJSON(): object;
5
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UnauthenticatedError = void 0;
4
+ const AppError_1 = require("./AppError");
5
+ class UnauthenticatedError extends AppError_1.ApplicationError {
6
+ constructor() {
7
+ super("Unauthenticated", "USER_UNAUTHENTICATED");
8
+ }
9
+ toJSON() {
10
+ return { name: this.name, message: this.message };
11
+ }
12
+ }
13
+ exports.UnauthenticatedError = UnauthenticatedError;
@@ -0,0 +1,8 @@
1
+ export declare enum JwtErrorCodes {
2
+ EMAIL_VERIFICATION_JWT_VERIFY_ERROR = "Invalid email verification jwt",
3
+ REFRESH_TOKEN_VERIFY_ERROR = "Invalid refresh token",
4
+ ACCESS_TOKEN_VERIFY_ERROR = "Invalid access token",
5
+ INVALID_TOKEN_ERROR = "Invalid token",
6
+ INVALID_TOKEN_ROLE_ERROR = "Invalid role identifier",
7
+ TOKEN_ROLE_MISMATCH_ERROR = "Role mismatch between payload and header"
8
+ }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JwtErrorCodes = void 0;
4
+ var JwtErrorCodes;
5
+ (function (JwtErrorCodes) {
6
+ JwtErrorCodes["EMAIL_VERIFICATION_JWT_VERIFY_ERROR"] = "Invalid email verification jwt";
7
+ JwtErrorCodes["REFRESH_TOKEN_VERIFY_ERROR"] = "Invalid refresh token";
8
+ JwtErrorCodes["ACCESS_TOKEN_VERIFY_ERROR"] = "Invalid access token";
9
+ JwtErrorCodes["INVALID_TOKEN_ERROR"] = "Invalid token";
10
+ JwtErrorCodes["INVALID_TOKEN_ROLE_ERROR"] = "Invalid role identifier";
11
+ JwtErrorCodes["TOKEN_ROLE_MISMATCH_ERROR"] = "Role mismatch between payload and header";
12
+ })(JwtErrorCodes || (exports.JwtErrorCodes = JwtErrorCodes = {}));
@@ -0,0 +1,7 @@
1
+ export * from "./errors/AppError";
2
+ export * from "./errors/JwtErrors";
3
+ export * from "./errors/UnauthenticatedError";
4
+ export * from "./errors/codes/JwtErrorCodes";
5
+ export * from "./jwt-utils/JwtHelper";
6
+ export * from "./middlewares/authMiddleware";
7
+ export * from "./types/UserRoles";
package/build/index.js ADDED
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./errors/AppError"), exports);
18
+ __exportStar(require("./errors/JwtErrors"), exports);
19
+ __exportStar(require("./errors/UnauthenticatedError"), exports);
20
+ __exportStar(require("./errors/codes/JwtErrorCodes"), exports);
21
+ __exportStar(require("./jwt-utils/JwtHelper"), exports);
22
+ __exportStar(require("./middlewares/authMiddleware"), exports);
23
+ __exportStar(require("./types/UserRoles"), exports);
@@ -0,0 +1,23 @@
1
+ import { UserRoles } from "../types/UserRoles";
2
+ export type tokenBody = {
3
+ userId: string;
4
+ email: string;
5
+ role: Exclude<UserRoles, "ADMIN">;
6
+ } | {
7
+ userId: string;
8
+ username: string;
9
+ role: "ADMIN";
10
+ };
11
+ export type JWTPayload = tokenBody & {
12
+ iat: number;
13
+ exp: number;
14
+ };
15
+ export declare class JwtHelper {
16
+ private _AccessSecrets;
17
+ constructor({ userAccessTokenSecret, expertAccessTokenSecret, adminAccessTokenSecret, }: {
18
+ userAccessTokenSecret: string;
19
+ expertAccessTokenSecret: string;
20
+ adminAccessTokenSecret: string;
21
+ });
22
+ verifyAccessToken: (jwtToken: string) => JWTPayload;
23
+ }
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.JwtHelper = void 0;
7
+ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
8
+ const JwtErrors_1 = require("../errors/JwtErrors");
9
+ function isUserRole(role) {
10
+ return ["ADMIN", "EXPERT", "USER"].includes(role);
11
+ }
12
+ class JwtHelper {
13
+ constructor({ userAccessTokenSecret, expertAccessTokenSecret, adminAccessTokenSecret, }) {
14
+ this.verifyAccessToken = (jwtToken) => {
15
+ const decoded = jsonwebtoken_1.default.decode(jwtToken, { complete: true });
16
+ if (!decoded || !decoded.header) {
17
+ throw new JwtErrors_1.InvalidTokenError();
18
+ }
19
+ const header = decoded.header;
20
+ const role = header.kid;
21
+ if (!role || !isUserRole(role)) {
22
+ throw new JwtErrors_1.InvalidTokenRoleError();
23
+ }
24
+ let payload;
25
+ try {
26
+ payload = jsonwebtoken_1.default.verify(jwtToken, this._AccessSecrets[role]);
27
+ }
28
+ catch (err) {
29
+ throw new JwtErrors_1.AccessTokenVerifyError();
30
+ }
31
+ if (!(role === payload.role)) {
32
+ throw new JwtErrors_1.TokenRoleMismatchError();
33
+ }
34
+ return payload;
35
+ };
36
+ this._AccessSecrets = {
37
+ USER: userAccessTokenSecret,
38
+ ADMIN: adminAccessTokenSecret,
39
+ EXPERT: expertAccessTokenSecret,
40
+ };
41
+ }
42
+ }
43
+ exports.JwtHelper = JwtHelper;
@@ -0,0 +1,6 @@
1
+ import { RequestHandler } from "express";
2
+ export declare class AuthMiddleware {
3
+ private _jwtHelper;
4
+ constructor(userAccessTokenSecret: string, expertAccessTokenSecret: string, adminAccessTokenSecret: string);
5
+ verify: RequestHandler;
6
+ }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AuthMiddleware = void 0;
4
+ const UnauthenticatedError_1 = require("../errors/UnauthenticatedError");
5
+ const JwtHelper_1 = require("../jwt-utils/JwtHelper");
6
+ class AuthMiddleware {
7
+ constructor(userAccessTokenSecret, expertAccessTokenSecret, adminAccessTokenSecret) {
8
+ this.verify = (req, _res, next) => {
9
+ var _a;
10
+ try {
11
+ const token = (_a = req.headers["authorization"]) === null || _a === void 0 ? void 0 : _a.split(" ")[1];
12
+ if (!token) {
13
+ throw new UnauthenticatedError_1.UnauthenticatedError();
14
+ }
15
+ const payload = this._jwtHelper.verifyAccessToken(token);
16
+ req.user = Object.assign(Object.assign({ id: payload.userId }, (payload.role === "ADMIN"
17
+ ? { userame: payload.username }
18
+ : { email: payload.email })), { role: payload.role });
19
+ next();
20
+ }
21
+ catch (err) {
22
+ next(err);
23
+ }
24
+ };
25
+ this._jwtHelper = new JwtHelper_1.JwtHelper({
26
+ userAccessTokenSecret,
27
+ expertAccessTokenSecret,
28
+ adminAccessTokenSecret,
29
+ });
30
+ }
31
+ }
32
+ exports.AuthMiddleware = AuthMiddleware;
@@ -0,0 +1,2 @@
1
+ export declare const USER_ROLES: readonly ["USER", "EXPERT", "ADMIN"];
2
+ export type UserRoles = (typeof USER_ROLES)[number];
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.USER_ROLES = void 0;
4
+ exports.USER_ROLES = ["USER", "EXPERT", "ADMIN"];
package/package.json CHANGED
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "name": "@skillstew/common",
3
- "version": "1.0.1",
4
- "main": "index.js",
5
- "scripts": {},
3
+ "version": "1.0.3",
4
+ "main": "./build/index.js",
5
+ "types": "./build/index.d.ts",
6
+ "scripts": {
7
+ "del": "del ./build/*",
8
+ "build": "npm run del && tsc",
9
+ "pub": "git add . && git commit -m \"Updates to common\" && npm version patch && npm run build && npm publish"
10
+ },
6
11
  "keywords": [],
7
12
  "author": "",
8
13
  "license": "ISC",
@@ -10,6 +15,7 @@
10
15
  "dependencies": {
11
16
  "@types/express": "^5.0.3",
12
17
  "@types/jsonwebtoken": "^9.0.10",
18
+ "del-cli": "^6.0.0",
13
19
  "express": "^5.1.0",
14
20
  "jsonwebtoken": "^9.0.2"
15
21
  }
package/src/index.ts CHANGED
@@ -0,0 +1,9 @@
1
+ export * from "./errors/AppError";
2
+ export * from "./errors/JwtErrors";
3
+ export * from "./errors/UnauthenticatedError";
4
+ export * from "./errors/codes/JwtErrorCodes";
5
+
6
+ export * from "./jwt-utils/JwtHelper";
7
+ export * from "./middlewares/authMiddleware";
8
+
9
+ export * from "./types/UserRoles";
package/tsconfig.json CHANGED
@@ -54,14 +54,14 @@
54
54
  // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
55
55
 
56
56
  /* Emit */
57
- // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
57
+ "declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */,
58
58
  // "declarationMap": true, /* Create sourcemaps for d.ts files. */
59
59
  // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
60
60
  // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
61
61
  // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
62
62
  // "noEmit": true, /* Disable emitting files from a compilation. */
63
63
  // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
64
- // "outDir": "./", /* Specify an output folder for all emitted files. */
64
+ "outDir": "./build" /* Specify an output folder for all emitted files. */,
65
65
  // "removeComments": true, /* Disable emitting comments. */
66
66
  // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
67
67
  // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */