@ilman00/authkit 1.0.0 → 2.0.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/dist/config/auth.config.d.ts.map +1 -1
- package/dist/config/auth.config.js +8 -13
- package/dist/config/auth.config.js.map +1 -1
- package/dist/handlers/email.handler.d.ts +6 -0
- package/dist/handlers/email.handler.d.ts.map +1 -0
- package/dist/handlers/email.handler.js +96 -0
- package/dist/handlers/email.handler.js.map +1 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/middleware/protect.d.ts +1 -1
- package/dist/middleware/protect.d.ts.map +1 -1
- package/dist/middleware/protect.js +27 -21
- package/dist/middleware/protect.js.map +1 -1
- package/dist/services/auth.service.d.ts +1 -0
- package/dist/services/auth.service.d.ts.map +1 -1
- package/dist/services/auth.service.js +19 -2
- package/dist/services/auth.service.js.map +1 -1
- package/dist/services/email.service.d.ts +17 -0
- package/dist/services/email.service.d.ts.map +1 -0
- package/dist/services/email.service.js +58 -0
- package/dist/services/email.service.js.map +1 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +12 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.config.d.ts","sourceRoot":"","sources":["../../src/config/auth.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAUtC,wBAAgB,UAAU,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"auth.config.d.ts","sourceRoot":"","sources":["../../src/config/auth.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAUtC,wBAAgB,UAAU,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAgBvD;AAED,wBAAgB,SAAS,IAAI,UAAU,CAGtC"}
|
|
@@ -9,30 +9,25 @@ const REQUIRED_ADAPTER_METHODS = [
|
|
|
9
9
|
"createUser",
|
|
10
10
|
];
|
|
11
11
|
function initConfig(userConfig) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
// Validate adapter
|
|
17
|
-
if (!userConfig.adapter) {
|
|
18
|
-
throw new Error("[my-auth-kit] adapter is required");
|
|
19
|
-
}
|
|
12
|
+
if (!userConfig.secret)
|
|
13
|
+
throw new Error("[authkit] secret is required");
|
|
14
|
+
if (!userConfig.adapter)
|
|
15
|
+
throw new Error("[authkit] adapter is required");
|
|
20
16
|
for (const method of REQUIRED_ADAPTER_METHODS) {
|
|
21
17
|
if (typeof userConfig.adapter[method] !== "function") {
|
|
22
|
-
throw new Error(`[
|
|
18
|
+
throw new Error(`[authkit] adapter missing required method: "${method}"`);
|
|
23
19
|
}
|
|
24
20
|
}
|
|
25
|
-
// Store with defaults
|
|
26
21
|
config = {
|
|
27
22
|
accessTokenExpiry: "15m",
|
|
28
23
|
refreshTokenExpiry: "7d",
|
|
24
|
+
verificationUrl: "http://localhost:3000", // sensible default
|
|
29
25
|
...userConfig,
|
|
30
26
|
};
|
|
31
27
|
}
|
|
32
28
|
function getConfig() {
|
|
33
|
-
if (!config)
|
|
34
|
-
throw new Error("[
|
|
35
|
-
}
|
|
29
|
+
if (!config)
|
|
30
|
+
throw new Error("[authkit] call init() before using auth");
|
|
36
31
|
return config;
|
|
37
32
|
}
|
|
38
33
|
//# sourceMappingURL=auth.config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.config.js","sourceRoot":"","sources":["../../src/config/auth.config.ts"],"names":[],"mappings":";;AAUA,
|
|
1
|
+
{"version":3,"file":"auth.config.js","sourceRoot":"","sources":["../../src/config/auth.config.ts"],"names":[],"mappings":";;AAUA,gCAgBC;AAED,8BAGC;AA7BD,IAAI,MAAM,GAAsB,IAAI,CAAC;AAErC,MAAM,wBAAwB,GAAG;IAC/B,iBAAiB;IACjB,cAAc;IACd,YAAY;CACJ,CAAC;AAEX,SAAgB,UAAU,CAAC,UAAsB;IAC/C,IAAI,CAAC,UAAU,CAAC,MAAM;QAAG,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACzE,IAAI,CAAC,UAAU,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAE1E,KAAK,MAAM,MAAM,IAAI,wBAAwB,EAAE,CAAC;QAC9C,IAAI,OAAO,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,UAAU,EAAE,CAAC;YACrD,MAAM,IAAI,KAAK,CAAC,+CAA+C,MAAM,GAAG,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAED,MAAM,GAAG;QACP,iBAAiB,EAAG,KAAK;QACzB,kBAAkB,EAAE,IAAI;QACxB,eAAe,EAAK,uBAAuB,EAAG,mBAAmB;QACjE,GAAG,UAAU;KACd,CAAC;AACJ,CAAC;AAED,SAAgB,SAAS;IACvB,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IACxE,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Response } from "express";
|
|
2
|
+
import { AuthRequest } from "../types";
|
|
3
|
+
export declare function verifyEmailHandler(req: AuthRequest, res: Response): Promise<void>;
|
|
4
|
+
export declare function forgotPasswordHandler(req: AuthRequest, res: Response): Promise<void>;
|
|
5
|
+
export declare function resetPasswordHandler(req: AuthRequest, res: Response): Promise<void>;
|
|
6
|
+
//# sourceMappingURL=email.handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.handler.d.ts","sourceRoot":"","sources":["../../src/handlers/email.handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAYvC,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,QAAQ,GACZ,OAAO,CAAC,IAAI,CAAC,CA2Bf;AAGD,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,QAAQ,GACZ,OAAO,CAAC,IAAI,CAAC,CAiCf;AAGD,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,QAAQ,GACZ,OAAO,CAAC,IAAI,CAAC,CA6Bf"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.verifyEmailHandler = verifyEmailHandler;
|
|
4
|
+
exports.forgotPasswordHandler = forgotPasswordHandler;
|
|
5
|
+
exports.resetPasswordHandler = resetPasswordHandler;
|
|
6
|
+
const errors_1 = require("../utils/errors");
|
|
7
|
+
const email_service_1 = require("../services/email.service");
|
|
8
|
+
const password_service_1 = require("../services/password.service");
|
|
9
|
+
// POST /verify-email { token }
|
|
10
|
+
async function verifyEmailHandler(req, res) {
|
|
11
|
+
try {
|
|
12
|
+
const { adapter } = (0, email_service_1.requireEmailConfig)();
|
|
13
|
+
const { token } = req.body;
|
|
14
|
+
if (!token)
|
|
15
|
+
throw new errors_1.AuthError("Token is required", 400);
|
|
16
|
+
const record = await adapter.findVerificationToken(token);
|
|
17
|
+
if (!record)
|
|
18
|
+
throw new errors_1.AuthError("Invalid or expired token", 400);
|
|
19
|
+
if (record.type !== "email_verification")
|
|
20
|
+
throw new errors_1.AuthError("Invalid token type", 400);
|
|
21
|
+
if (record.expiresAt < new Date())
|
|
22
|
+
throw new errors_1.AuthError("Token has expired", 400);
|
|
23
|
+
await adapter.updateUser(record.userId, { isVerified: true });
|
|
24
|
+
await adapter.deleteVerificationToken(token);
|
|
25
|
+
res.status(200).json({ message: "Email verified successfully" });
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
if (err instanceof errors_1.AuthError) {
|
|
29
|
+
res.status(err.statusCode).json({ message: err.message });
|
|
30
|
+
}
|
|
31
|
+
else if (err instanceof Error) {
|
|
32
|
+
res.status(400).json({ message: err.message });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// POST /forgot-password { email }
|
|
37
|
+
async function forgotPasswordHandler(req, res) {
|
|
38
|
+
try {
|
|
39
|
+
const { adapter } = (0, email_service_1.requireEmailConfig)();
|
|
40
|
+
const { email } = req.body;
|
|
41
|
+
if (!email)
|
|
42
|
+
throw new errors_1.AuthError("Email is required", 400);
|
|
43
|
+
const user = await adapter.findUserByEmail(email);
|
|
44
|
+
// Always respond with 200 — never reveal if email exists or not
|
|
45
|
+
if (!user) {
|
|
46
|
+
res.status(200).json({ message: "If that email exists, a reset link has been sent" });
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const token = (0, email_service_1.generateToken)();
|
|
50
|
+
await adapter.saveVerificationToken({
|
|
51
|
+
token,
|
|
52
|
+
userId: user.id,
|
|
53
|
+
type: "password_reset",
|
|
54
|
+
expiresAt: (0, email_service_1.getExpiryDate)(15), // 15 minutes
|
|
55
|
+
});
|
|
56
|
+
await (0, email_service_1.sendPasswordResetEmail)(user.email, token);
|
|
57
|
+
res.status(200).json({ message: "If that email exists, a reset link has been sent" });
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
if (err instanceof errors_1.AuthError) {
|
|
61
|
+
res.status(err.statusCode).json({ message: err.message });
|
|
62
|
+
}
|
|
63
|
+
else if (err instanceof Error) {
|
|
64
|
+
res.status(400).json({ message: err.message });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// POST /reset-password { token, newPassword }
|
|
69
|
+
async function resetPasswordHandler(req, res) {
|
|
70
|
+
try {
|
|
71
|
+
const { adapter } = (0, email_service_1.requireEmailConfig)();
|
|
72
|
+
const { token, newPassword } = req.body;
|
|
73
|
+
if (!token || !newPassword)
|
|
74
|
+
throw new errors_1.AuthError("Token and newPassword are required", 400);
|
|
75
|
+
const record = await adapter.findVerificationToken(token);
|
|
76
|
+
if (!record)
|
|
77
|
+
throw new errors_1.AuthError("Invalid or expired token", 400);
|
|
78
|
+
if (record.type !== "password_reset")
|
|
79
|
+
throw new errors_1.AuthError("Invalid token type", 400);
|
|
80
|
+
if (record.expiresAt < new Date())
|
|
81
|
+
throw new errors_1.AuthError("Token has expired", 400);
|
|
82
|
+
const hashed = await (0, password_service_1.hashPassword)(newPassword);
|
|
83
|
+
await adapter.updateUser(record.userId, { password: hashed });
|
|
84
|
+
await adapter.deleteVerificationToken(token);
|
|
85
|
+
res.status(200).json({ message: "Password reset successfully" });
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
if (err instanceof errors_1.AuthError) {
|
|
89
|
+
res.status(err.statusCode).json({ message: err.message });
|
|
90
|
+
}
|
|
91
|
+
else if (err instanceof Error) {
|
|
92
|
+
res.status(400).json({ message: err.message });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=email.handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.handler.js","sourceRoot":"","sources":["../../src/handlers/email.handler.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { registerHandler, loginHandler } from "./handlers/auth.handler";
|
|
2
2
|
import { protect } from "./middleware/protect";
|
|
3
|
-
import {
|
|
3
|
+
import { verifyEmailHandler, forgotPasswordHandler, resetPasswordHandler } from "./handlers/email.handler";
|
|
4
|
+
import { AuthConfig, AuthAdapter, AuthUser, AuthRequest, VerificationToken } from "./types";
|
|
4
5
|
export declare function init(config: AuthConfig): void;
|
|
5
|
-
export { registerHandler, loginHandler, protect };
|
|
6
|
-
export type { AuthConfig, AuthAdapter, AuthUser, AuthRequest };
|
|
6
|
+
export { registerHandler, loginHandler, protect, verifyEmailHandler, forgotPasswordHandler, resetPasswordHandler, };
|
|
7
|
+
export type { AuthConfig, AuthAdapter, AuthUser, AuthRequest, VerificationToken };
|
|
7
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,EACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE5F,wBAAgB,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAE7C;AAED,OAAO,EACL,eAAe,EACf,YAAY,EACZ,OAAO,EACP,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,GACrB,CAAC;AAEF,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.protect = exports.loginHandler = exports.registerHandler = void 0;
|
|
3
|
+
exports.resetPasswordHandler = exports.forgotPasswordHandler = exports.verifyEmailHandler = exports.protect = exports.loginHandler = exports.registerHandler = void 0;
|
|
4
4
|
exports.init = init;
|
|
5
5
|
const auth_config_1 = require("./config/auth.config");
|
|
6
6
|
const auth_handler_1 = require("./handlers/auth.handler");
|
|
@@ -8,6 +8,10 @@ Object.defineProperty(exports, "registerHandler", { enumerable: true, get: funct
|
|
|
8
8
|
Object.defineProperty(exports, "loginHandler", { enumerable: true, get: function () { return auth_handler_1.loginHandler; } });
|
|
9
9
|
const protect_1 = require("./middleware/protect");
|
|
10
10
|
Object.defineProperty(exports, "protect", { enumerable: true, get: function () { return protect_1.protect; } });
|
|
11
|
+
const email_handler_1 = require("./handlers/email.handler");
|
|
12
|
+
Object.defineProperty(exports, "verifyEmailHandler", { enumerable: true, get: function () { return email_handler_1.verifyEmailHandler; } });
|
|
13
|
+
Object.defineProperty(exports, "forgotPasswordHandler", { enumerable: true, get: function () { return email_handler_1.forgotPasswordHandler; } });
|
|
14
|
+
Object.defineProperty(exports, "resetPasswordHandler", { enumerable: true, get: function () { return email_handler_1.resetPasswordHandler; } });
|
|
11
15
|
function init(config) {
|
|
12
16
|
(0, auth_config_1.initConfig)(config);
|
|
13
17
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAUA,oBAEC;AAZD,sDAAkD;AAClD,0DAAwE;AActE,gGAdO,8BAAe,OAcP;AACf,6FAfwB,2BAAY,OAexB;AAdd,kDAA+C;AAe7C,wFAfO,iBAAO,OAeP;AAdT,4DAIkC;AAWhC,mGAdA,kCAAkB,OAcA;AAClB,sGAdA,qCAAqB,OAcA;AACrB,qGAdA,oCAAoB,OAcA;AAVtB,SAAgB,IAAI,CAAC,MAAkB;IACrC,IAAA,wBAAU,EAAC,MAAM,CAAC,CAAC;AACrB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Response, NextFunction } from "express";
|
|
2
2
|
import { AuthRequest } from "../types";
|
|
3
|
-
export declare function protect(req: AuthRequest, res: Response, next: NextFunction)
|
|
3
|
+
export declare function protect(...allowedRoles: string[]): (req: AuthRequest, res: Response, next: NextFunction) => Promise<void>;
|
|
4
4
|
//# sourceMappingURL=protect.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protect.d.ts","sourceRoot":"","sources":["../../src/middleware/protect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGjD,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"protect.d.ts","sourceRoot":"","sources":["../../src/middleware/protect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGjD,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAIvC,wBAAgB,OAAO,CAAC,GAAG,YAAY,EAAE,MAAM,EAAE,IACjC,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,KAAG,OAAO,CAAC,IAAI,CAAC,CA2BlF"}
|
|
@@ -4,28 +4,34 @@ exports.protect = protect;
|
|
|
4
4
|
const jwt_service_1 = require("../services/jwt.service");
|
|
5
5
|
const auth_config_1 = require("../config/auth.config");
|
|
6
6
|
const errors_1 = require("../utils/errors");
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
// ✅ Now accepts optional roles
|
|
8
|
+
function protect(...allowedRoles) {
|
|
9
|
+
return async (req, res, next) => {
|
|
10
|
+
try {
|
|
11
|
+
const authHeader = req.headers.authorization;
|
|
12
|
+
if (!authHeader?.startsWith("Bearer "))
|
|
13
|
+
throw new errors_1.AuthError("No token provided", 401);
|
|
14
|
+
const token = authHeader.split(" ")[1];
|
|
15
|
+
const decoded = (0, jwt_service_1.verifyToken)(token);
|
|
16
|
+
const { adapter } = (0, auth_config_1.getConfig)();
|
|
17
|
+
const user = await adapter.findUserById(decoded.id);
|
|
18
|
+
if (!user)
|
|
19
|
+
throw new errors_1.AuthError("User no longer exists", 401);
|
|
20
|
+
// ✅ Role check — only runs if roles were specified
|
|
21
|
+
if (allowedRoles.length > 0 && !allowedRoles.includes(user.role ?? "")) {
|
|
22
|
+
throw new errors_1.AuthError("Forbidden: insufficient permissions", 403);
|
|
23
|
+
}
|
|
24
|
+
req.user = user;
|
|
25
|
+
next();
|
|
12
26
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
next();
|
|
21
|
-
}
|
|
22
|
-
catch (err) {
|
|
23
|
-
if (err instanceof errors_1.AuthError) {
|
|
24
|
-
res.status(err.statusCode).json({ message: err.message });
|
|
27
|
+
catch (err) {
|
|
28
|
+
if (err instanceof errors_1.AuthError) {
|
|
29
|
+
res.status(err.statusCode).json({ message: err.message });
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
res.status(401).json({ message: "Invalid or expired token" });
|
|
33
|
+
}
|
|
25
34
|
}
|
|
26
|
-
|
|
27
|
-
res.status(401).json({ message: "Invalid or expired token" });
|
|
28
|
-
}
|
|
29
|
-
}
|
|
35
|
+
};
|
|
30
36
|
}
|
|
31
37
|
//# sourceMappingURL=protect.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protect.js","sourceRoot":"","sources":["../../src/middleware/protect.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"protect.js","sourceRoot":"","sources":["../../src/middleware/protect.ts"],"names":[],"mappings":";;AAOA,0BA4BC;AAlCD,yDAAsD;AACtD,uDAAkD;AAElD,4CAA4C;AAE5C,+BAA+B;AAC/B,SAAgB,OAAO,CAAC,GAAG,YAAsB;IAC/C,OAAO,KAAK,EAAE,GAAgB,EAAE,GAAa,EAAE,IAAkB,EAAiB,EAAE;QAClF,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC;YAC7C,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,SAAS,CAAC;gBAAE,MAAM,IAAI,kBAAS,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC;YAEtF,MAAM,KAAK,GAAK,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACzC,MAAM,OAAO,GAAG,IAAA,yBAAW,EAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,EAAE,OAAO,EAAE,GAAG,IAAA,uBAAS,GAAE,CAAC;YAChC,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACpD,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,kBAAS,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;YAE7D,mDAAmD;YACnD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC;gBACvE,MAAM,IAAI,kBAAS,CAAC,qCAAqC,EAAE,GAAG,CAAC,CAAC;YAClE,CAAC;YAED,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;YAChB,IAAI,EAAE,CAAC;QACT,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,kBAAS,EAAE,CAAC;gBAC7B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5D,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAC,CAAC;YAChE,CAAC;QACH,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.service.d.ts","sourceRoot":"","sources":["../../src/services/auth.service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.service.d.ts","sourceRoot":"","sources":["../../src/services/auth.service.ts"],"names":[],"mappings":"AASA,wBAAsB,YAAY,CAAC,QAAQ,EAAE;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBhB;AAED,wBAAsB,SAAS,CAC7B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CASxD"}
|
|
@@ -5,13 +5,30 @@ exports.loginUser = loginUser;
|
|
|
5
5
|
const password_service_1 = require("./password.service");
|
|
6
6
|
const jwt_service_1 = require("./jwt.service");
|
|
7
7
|
const auth_config_1 = require("../config/auth.config");
|
|
8
|
+
const email_service_1 = require("./email.service");
|
|
8
9
|
async function registerUser(userData) {
|
|
9
|
-
const { adapter } = (0, auth_config_1.getConfig)();
|
|
10
|
+
const { adapter, emailSender } = (0, auth_config_1.getConfig)();
|
|
10
11
|
const existing = await adapter.findUserByEmail(userData.email);
|
|
11
12
|
if (existing)
|
|
12
13
|
throw new Error("User already exists");
|
|
13
14
|
const hashed = await (0, password_service_1.hashPassword)(userData.password);
|
|
14
|
-
await adapter.createUser({
|
|
15
|
+
const user = await adapter.createUser({
|
|
16
|
+
...userData,
|
|
17
|
+
password: hashed,
|
|
18
|
+
isVerified: false, // always false on register
|
|
19
|
+
});
|
|
20
|
+
// Only send verification email if emailSender is configured
|
|
21
|
+
// If not — silently skip (backward compatible)
|
|
22
|
+
if (emailSender && adapter.saveVerificationToken) {
|
|
23
|
+
const token = (0, email_service_1.generateToken)();
|
|
24
|
+
await adapter.saveVerificationToken({
|
|
25
|
+
token,
|
|
26
|
+
userId: user.id,
|
|
27
|
+
type: "email_verification",
|
|
28
|
+
expiresAt: (0, email_service_1.getExpiryDate)(24 * 60), // 24 hours
|
|
29
|
+
});
|
|
30
|
+
await (0, email_service_1.sendVerificationEmail)(user.email, token);
|
|
31
|
+
}
|
|
15
32
|
}
|
|
16
33
|
async function loginUser(email, password) {
|
|
17
34
|
const { adapter } = (0, auth_config_1.getConfig)();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.service.js","sourceRoot":"","sources":["../../src/services/auth.service.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"auth.service.js","sourceRoot":"","sources":["../../src/services/auth.service.ts"],"names":[],"mappings":";;AASA,oCA8BC;AAED,8BAYC;AArDD,yDAAmE;AACnE,+CAAkE;AAClE,uDAAkD;AAClD,mDAIyB;AAElB,KAAK,UAAU,YAAY,CAAC,QAKlC;IACC,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,IAAA,uBAAS,GAAE,CAAC;IAE7C,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC/D,IAAI,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAErD,MAAM,MAAM,GAAG,MAAM,IAAA,+BAAY,EAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACrD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC;QACpC,GAAG,QAAQ;QACX,QAAQ,EAAE,MAAM;QAChB,UAAU,EAAE,KAAK,EAAU,2BAA2B;KACvD,CAAC,CAAC;IAEH,4DAA4D;IAC5D,+CAA+C;IAC/C,IAAI,WAAW,IAAI,OAAO,CAAC,qBAAqB,EAAE,CAAC;QACjD,MAAM,KAAK,GAAG,IAAA,6BAAa,GAAE,CAAC;QAC9B,MAAM,OAAO,CAAC,qBAAqB,CAAC;YAClC,KAAK;YACL,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,IAAI,EAAO,oBAAoB;YAC/B,SAAS,EAAE,IAAA,6BAAa,EAAC,EAAE,GAAG,EAAE,CAAC,EAAE,WAAW;SAC/C,CAAC,CAAC;QACH,MAAM,IAAA,qCAAqB,EAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,SAAS,CAC7B,KAAa,EACb,QAAgB;IAEhB,MAAM,EAAE,OAAO,EAAE,GAAG,IAAA,uBAAS,GAAE,CAAC;IAChC,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAClD,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,MAAM,IAAA,kCAAe,EAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC/D,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACrD,MAAM,WAAW,GAAI,IAAA,6BAAe,EAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,YAAY,GAAG,IAAA,8BAAgB,EAAC,IAAI,CAAC,CAAC;IAC5C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { AuthConfig } from "../types";
|
|
2
|
+
type EmailReadyConfig = Omit<AuthConfig, "adapter" | "emailSender"> & {
|
|
3
|
+
emailSender: Required<AuthConfig>["emailSender"];
|
|
4
|
+
adapter: Omit<AuthConfig["adapter"], "updateUser" | "saveVerificationToken" | "findVerificationToken" | "deleteVerificationToken"> & {
|
|
5
|
+
updateUser: Required<AuthConfig["adapter"]>["updateUser"];
|
|
6
|
+
saveVerificationToken: Required<AuthConfig["adapter"]>["saveVerificationToken"];
|
|
7
|
+
findVerificationToken: Required<AuthConfig["adapter"]>["findVerificationToken"];
|
|
8
|
+
deleteVerificationToken: Required<AuthConfig["adapter"]>["deleteVerificationToken"];
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
export declare function requireEmailConfig(): EmailReadyConfig;
|
|
12
|
+
export declare function generateToken(): string;
|
|
13
|
+
export declare function getExpiryDate(minutes: number): Date;
|
|
14
|
+
export declare function sendVerificationEmail(to: string, token: string): Promise<void>;
|
|
15
|
+
export declare function sendPasswordResetEmail(to: string, token: string): Promise<void>;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=email.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.service.d.ts","sourceRoot":"","sources":["../../src/services/email.service.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGtC,KAAK,gBAAgB,GAAG,IAAI,CAAC,UAAU,EAAE,SAAS,GAAG,aAAa,CAAC,GAAG;IACpE,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,aAAa,CAAC,CAAC;IACjD,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EACjC,YAAY,GAAG,uBAAuB,GAAG,uBAAuB,GAAG,yBAAyB,CAC7F,GAAG;QACF,UAAU,EAAe,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;QACvE,qBAAqB,EAAI,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC;QAClF,qBAAqB,EAAI,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC;QAClF,uBAAuB,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC;KACrF,CAAC;CACH,CAAC;AAEF,wBAAgB,kBAAkB,IAAI,gBAAgB,CAerD;AAGD,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEnD;AAID,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAsB,sBAAsB,CAC1C,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAaf"}
|
|
@@ -0,0 +1,58 @@
|
|
|
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.requireEmailConfig = requireEmailConfig;
|
|
7
|
+
exports.generateToken = generateToken;
|
|
8
|
+
exports.getExpiryDate = getExpiryDate;
|
|
9
|
+
exports.sendVerificationEmail = sendVerificationEmail;
|
|
10
|
+
exports.sendPasswordResetEmail = sendPasswordResetEmail;
|
|
11
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
12
|
+
const auth_config_1 = require("../config/auth.config");
|
|
13
|
+
const errors_1 = require("../utils/errors");
|
|
14
|
+
function requireEmailConfig() {
|
|
15
|
+
const config = (0, auth_config_1.getConfig)();
|
|
16
|
+
if (!config.emailSender)
|
|
17
|
+
throw new errors_1.AuthError("[authkit] emailSender is required to use email features", 500);
|
|
18
|
+
if (!config.adapter.updateUser)
|
|
19
|
+
throw new errors_1.AuthError("[authkit] adapter.updateUser is required", 500);
|
|
20
|
+
if (!config.adapter.saveVerificationToken)
|
|
21
|
+
throw new errors_1.AuthError("[authkit] adapter.saveVerificationToken is required", 500);
|
|
22
|
+
if (!config.adapter.findVerificationToken)
|
|
23
|
+
throw new errors_1.AuthError("[authkit] adapter.findVerificationToken is required", 500);
|
|
24
|
+
if (!config.adapter.deleteVerificationToken)
|
|
25
|
+
throw new errors_1.AuthError("[authkit] adapter.deleteVerificationToken is required", 500);
|
|
26
|
+
return config; // safe — all fields confirmed above
|
|
27
|
+
}
|
|
28
|
+
// ---- Token helpers -----------------------------------------------
|
|
29
|
+
function generateToken() {
|
|
30
|
+
return crypto_1.default.randomBytes(32).toString("hex");
|
|
31
|
+
}
|
|
32
|
+
function getExpiryDate(minutes) {
|
|
33
|
+
return new Date(Date.now() + minutes * 60 * 1000);
|
|
34
|
+
}
|
|
35
|
+
// ---- Email senders -----------------------------------------------
|
|
36
|
+
async function sendVerificationEmail(to, token) {
|
|
37
|
+
const { emailSender, verificationUrl } = requireEmailConfig();
|
|
38
|
+
const link = `${verificationUrl}/verify-email?token=${token}`;
|
|
39
|
+
const html = `
|
|
40
|
+
<h2>Verify your email</h2>
|
|
41
|
+
<p>Click the link below to verify your email address. This link expires in 24 hours.</p>
|
|
42
|
+
<a href="${link}">${link}</a>
|
|
43
|
+
<p>If you did not create an account, ignore this email.</p>
|
|
44
|
+
`;
|
|
45
|
+
await emailSender(to, "Verify your email", html);
|
|
46
|
+
}
|
|
47
|
+
async function sendPasswordResetEmail(to, token) {
|
|
48
|
+
const { emailSender, verificationUrl } = requireEmailConfig();
|
|
49
|
+
const link = `${verificationUrl}/reset-password?token=${token}`;
|
|
50
|
+
const html = `
|
|
51
|
+
<h2>Reset your password</h2>
|
|
52
|
+
<p>Click the link below to reset your password. This link expires in 15 minutes.</p>
|
|
53
|
+
<a href="${link}">${link}</a>
|
|
54
|
+
<p>If you did not request a password reset, ignore this email.</p>
|
|
55
|
+
`;
|
|
56
|
+
await emailSender(to, "Reset your password", html);
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=email.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.service.js","sourceRoot":"","sources":["../../src/services/email.service.ts"],"names":[],"mappings":";;;;;AAoBA,gDAeC;AAGD,sCAEC;AAED,sCAEC;AAID,sDAgBC;AAED,wDAgBC;AAlFD,oDAA4B;AAC5B,uDAAkD;AAClD,4CAA4C;AAkB5C,SAAgB,kBAAkB;IAChC,MAAM,MAAM,GAAG,IAAA,uBAAS,GAAE,CAAC;IAE3B,IAAI,CAAC,MAAM,CAAC,WAAW;QACrB,MAAM,IAAI,kBAAS,CAAC,yDAAyD,EAAE,GAAG,CAAC,CAAC;IACtF,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU;QAC5B,MAAM,IAAI,kBAAS,CAAC,0CAA0C,EAAE,GAAG,CAAC,CAAC;IACvE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,qBAAqB;QACvC,MAAM,IAAI,kBAAS,CAAC,qDAAqD,EAAE,GAAG,CAAC,CAAC;IAClF,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,qBAAqB;QACvC,MAAM,IAAI,kBAAS,CAAC,qDAAqD,EAAE,GAAG,CAAC,CAAC;IAClF,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,uBAAuB;QACzC,MAAM,IAAI,kBAAS,CAAC,uDAAuD,EAAE,GAAG,CAAC,CAAC;IAEpF,OAAO,MAAqC,CAAC,CAAC,oCAAoC;AACpF,CAAC;AACD,qEAAqE;AAErE,SAAgB,aAAa;IAC3B,OAAO,gBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAChD,CAAC;AAED,SAAgB,aAAa,CAAC,OAAe;IAC3C,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;AACpD,CAAC;AAED,qEAAqE;AAE9D,KAAK,UAAU,qBAAqB,CACzC,EAAU,EACV,KAAa;IAEb,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,kBAAkB,EAAE,CAAC;IAE9D,MAAM,IAAI,GAAG,GAAG,eAAe,uBAAuB,KAAK,EAAE,CAAC;IAE9D,MAAM,IAAI,GAAG;;;eAGA,IAAI,KAAK,IAAI;;GAEzB,CAAC;IAEF,MAAM,WAAW,CAAC,EAAE,EAAE,mBAAmB,EAAE,IAAI,CAAC,CAAC;AACnD,CAAC;AAEM,KAAK,UAAU,sBAAsB,CAC1C,EAAU,EACV,KAAa;IAEb,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,kBAAkB,EAAE,CAAC;IAE9D,MAAM,IAAI,GAAG,GAAG,eAAe,yBAAyB,KAAK,EAAE,CAAC;IAEhE,MAAM,IAAI,GAAG;;;eAGA,IAAI,KAAK,IAAI;;GAEzB,CAAC;IAEF,MAAM,WAAW,CAAC,EAAE,EAAE,qBAAqB,EAAE,IAAI,CAAC,CAAC;AACrD,CAAC"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -4,16 +4,30 @@ export interface AuthUser {
|
|
|
4
4
|
email: string;
|
|
5
5
|
password: string;
|
|
6
6
|
role?: string;
|
|
7
|
+
isVerified?: boolean;
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
}
|
|
10
|
+
export interface VerificationToken {
|
|
11
|
+
token: string;
|
|
12
|
+
userId: string;
|
|
13
|
+
type: "email_verification" | "password_reset";
|
|
14
|
+
expiresAt: Date;
|
|
7
15
|
}
|
|
8
16
|
export interface AuthAdapter {
|
|
9
17
|
findUserByEmail: (email: string) => Promise<AuthUser | null>;
|
|
10
18
|
findUserById: (id: string) => Promise<AuthUser | null>;
|
|
11
19
|
createUser: (data: Partial<AuthUser>) => Promise<AuthUser>;
|
|
20
|
+
updateUser?: (id: string, data: Partial<AuthUser>) => Promise<AuthUser>;
|
|
21
|
+
saveVerificationToken?: (payload: VerificationToken) => Promise<void>;
|
|
22
|
+
findVerificationToken?: (token: string) => Promise<VerificationToken | null>;
|
|
23
|
+
deleteVerificationToken?: (token: string) => Promise<void>;
|
|
12
24
|
}
|
|
13
25
|
export interface AuthConfig {
|
|
14
26
|
secret: string;
|
|
15
27
|
accessTokenExpiry?: string;
|
|
16
28
|
refreshTokenExpiry?: string;
|
|
29
|
+
verificationUrl?: string;
|
|
30
|
+
emailSender?: (to: string, subject: string, html: string) => Promise<void>;
|
|
17
31
|
adapter: AuthAdapter;
|
|
18
32
|
}
|
|
19
33
|
export interface AuthRequest extends Request {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,oBAAoB,GAAG,gBAAgB,CAAC;IAC9C,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAE1B,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAC7D,YAAY,EAAK,CAAC,EAAE,EAAE,MAAM,KAAQ,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAC7D,UAAU,EAAO,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAGhE,UAAU,CAAC,EAAe,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACrF,qBAAqB,CAAC,EAAI,CAAC,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,qBAAqB,CAAC,EAAI,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IAC/E,uBAAuB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5D;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAG,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,eAAe,CAAC,EAAK,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,WAAY,SAAQ,OAAO;IAC1C,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ilman00/authkit",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Plug and play auth for Express apps",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
|
-
"files": [
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
8
10
|
"scripts": {
|
|
9
11
|
"build": "tsc",
|
|
10
12
|
"dev": "tsc --watch"
|
|
@@ -13,6 +15,7 @@
|
|
|
13
15
|
"express": "^4.x || ^5.x"
|
|
14
16
|
},
|
|
15
17
|
"dependencies": {
|
|
18
|
+
"@ilman00/authkit": "^1.0.0",
|
|
16
19
|
"bcryptjs": "^2.4.3",
|
|
17
20
|
"jsonwebtoken": "^9.0.0"
|
|
18
21
|
},
|
|
@@ -22,6 +25,11 @@
|
|
|
22
25
|
"@types/jsonwebtoken": "^9.0.0",
|
|
23
26
|
"typescript": "^5.0.0"
|
|
24
27
|
},
|
|
25
|
-
"keywords": [
|
|
28
|
+
"keywords": [
|
|
29
|
+
"auth",
|
|
30
|
+
"jwt",
|
|
31
|
+
"express",
|
|
32
|
+
"authentication"
|
|
33
|
+
],
|
|
26
34
|
"license": "MIT"
|
|
27
|
-
}
|
|
35
|
+
}
|