auth-verify 1.2.3 → 1.2.5
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/babel.config.js +3 -0
- package/index.js +3 -2
- package/package.json +20 -6
- package/src/jwt/index.js +3 -3
- package/tests/jwtmanager.test.js +39 -0
- package/assets/banner.png +0 -0
- package/test.js +0 -205
package/babel.config.js
ADDED
package/index.js
CHANGED
|
@@ -5,7 +5,7 @@ const OAuthManager = require("./src/oauth")
|
|
|
5
5
|
|
|
6
6
|
class AuthVerify {
|
|
7
7
|
constructor(options = {}) {
|
|
8
|
-
|
|
8
|
+
let {
|
|
9
9
|
jwtSecret,
|
|
10
10
|
otpExpiry = 300,
|
|
11
11
|
storeTokens = "none",
|
|
@@ -13,7 +13,8 @@ class AuthVerify {
|
|
|
13
13
|
redisUrl,
|
|
14
14
|
} = options;
|
|
15
15
|
|
|
16
|
-
if (!jwtSecret) throw new Error("jwtSecret is required in AuthVerify options");
|
|
16
|
+
// if (!jwtSecret) throw new Error("jwtSecret is required in AuthVerify options");
|
|
17
|
+
if (!jwtSecret) jwtSecret = 'JWT_AUTH_VERIFY_SECRET'
|
|
17
18
|
|
|
18
19
|
this.senderName;
|
|
19
20
|
this.jwt = new JWTManager(jwtSecret, { storeTokens });
|
package/package.json
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"dependencies": {
|
|
3
|
+
"auth-verify": "^1.2.4",
|
|
3
4
|
"axios": "^1.12.2",
|
|
4
5
|
"crypto": "^1.0.1",
|
|
5
|
-
"express": "^5.1.0",
|
|
6
6
|
"ioredis": "^5.8.1",
|
|
7
7
|
"jsonwebtoken": "^9.0.2",
|
|
8
8
|
"node-telegram-bot-api": "^0.66.0",
|
|
9
9
|
"nodemailer": "^7.0.6",
|
|
10
10
|
"redis": "^5.8.3",
|
|
11
11
|
"twilio": "^5.10.3",
|
|
12
|
-
"uuid": "^
|
|
12
|
+
"uuid": "^9.0.1"
|
|
13
13
|
},
|
|
14
14
|
"name": "auth-verify",
|
|
15
|
-
"version": "1.2.
|
|
16
|
-
"description": "A simple Node.js library for sending and verifying OTP via email",
|
|
15
|
+
"version": "1.2.5",
|
|
16
|
+
"description": "A simple Node.js library for sending and verifying OTP via email, SMS and Telegram bot",
|
|
17
17
|
"main": "index.js",
|
|
18
18
|
"scripts": {
|
|
19
|
-
"test": "
|
|
19
|
+
"test": "jest --runInBand"
|
|
20
20
|
},
|
|
21
21
|
"repository": {
|
|
22
22
|
"type": "git",
|
|
@@ -47,5 +47,19 @@
|
|
|
47
47
|
"bugs": {
|
|
48
48
|
"url": "https://github.com/jahongir2007/auth-verify/issues"
|
|
49
49
|
},
|
|
50
|
-
"homepage": "https://jahongir2007.github.io/auth-verify/"
|
|
50
|
+
"homepage": "https://jahongir2007.github.io/auth-verify/",
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@babel/preset-env": "^7.28.5",
|
|
53
|
+
"babel-jest": "^30.2.0",
|
|
54
|
+
"jest": "^30.2.0",
|
|
55
|
+
"supertest": "^7.1.4"
|
|
56
|
+
},
|
|
57
|
+
"jest": {
|
|
58
|
+
"transformIgnorePatterns": [
|
|
59
|
+
"node_modules/(?!(jsonwebtoken|ioredis)/)"
|
|
60
|
+
],
|
|
61
|
+
"transform": {
|
|
62
|
+
"^.+\\.jsx?$": "babel-jest"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
51
65
|
}
|
package/src/jwt/index.js
CHANGED
|
@@ -249,7 +249,7 @@ const CookieManager = require("./cookie");
|
|
|
249
249
|
class JWTManager {
|
|
250
250
|
constructor(secret, options = {}) {
|
|
251
251
|
// if (!secret) throw new Error("JWT secret is required");
|
|
252
|
-
this.secret = secret || "
|
|
252
|
+
this.secret = secret || "jwt_token";
|
|
253
253
|
this.storeType = options.storeTokens || "none";
|
|
254
254
|
|
|
255
255
|
if (this.storeType === "memory") {
|
|
@@ -307,7 +307,7 @@ class JWTManager {
|
|
|
307
307
|
|
|
308
308
|
// Auto cookie support
|
|
309
309
|
if (options.res) {
|
|
310
|
-
CookieManager.setCookie(options.res,
|
|
310
|
+
CookieManager.setCookie(options.res, this.secret, token, {
|
|
311
311
|
httpOnly: true,
|
|
312
312
|
secure: options.secure ?? true,
|
|
313
313
|
sameSite: "Strict",
|
|
@@ -325,7 +325,7 @@ class JWTManager {
|
|
|
325
325
|
// If request object provided
|
|
326
326
|
if (typeof input === "object" && input.headers) {
|
|
327
327
|
token =
|
|
328
|
-
CookieManager.getCookie(input,
|
|
328
|
+
CookieManager.getCookie(input, this.secret) ||
|
|
329
329
|
(input.headers.authorization
|
|
330
330
|
? input.headers.authorization.replace("Bearer ", "")
|
|
331
331
|
: null);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// tests/jwtManager.test.js
|
|
2
|
+
const AuthVerify = require('../index');
|
|
3
|
+
const express = require('express');
|
|
4
|
+
const request = require('supertest'); // for API tests
|
|
5
|
+
|
|
6
|
+
describe('JWTManager', () => {
|
|
7
|
+
let auth;
|
|
8
|
+
|
|
9
|
+
beforeAll(() => {
|
|
10
|
+
auth = new AuthVerify({jwtSecret: 'test_secret', storeTokens: 'memory'});
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test('should sign and verify a JWT', async () => {
|
|
14
|
+
const payload = { userId: 1 };
|
|
15
|
+
const token = await auth.jwt.sign(payload, '5s');
|
|
16
|
+
expect(typeof token).toBe('string');
|
|
17
|
+
|
|
18
|
+
const verified = await auth.jwt.verify(token);
|
|
19
|
+
expect(verified.userId).toBe(1);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('should fail after expiration', async () => {
|
|
23
|
+
const token = await auth.jwt.sign({ name: 'Jahongir' }, '1s');
|
|
24
|
+
await new Promise(r => setTimeout(r, 2000)); // wait 2s
|
|
25
|
+
await expect(auth.jwt.verify(token)).rejects.toThrow(/expired/i);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('should set cookie automatically if res is provided', async () => {
|
|
29
|
+
const app = express();
|
|
30
|
+
|
|
31
|
+
app.get('/login', async (req, res) => {
|
|
32
|
+
const token = await auth.jwt.sign({ userId: 123 }, '5s', { res });
|
|
33
|
+
res.json({ token });
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const res = await request(app).get('/login');
|
|
37
|
+
expect(res.headers['set-cookie']).toBeDefined();
|
|
38
|
+
});
|
|
39
|
+
});
|
package/assets/banner.png
DELETED
|
Binary file
|
package/test.js
DELETED
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
// const AuthVerify = require('./index'); // your library entry
|
|
2
|
-
// const auth = new AuthVerify({ jwtSecret: 's', storeTokens: 'memory', otpExpiry: 300 });
|
|
3
|
-
// const TelegramBot = require("node-telegram-bot-api");
|
|
4
|
-
|
|
5
|
-
// auth.otp.setSender({
|
|
6
|
-
// via: 'telegram'
|
|
7
|
-
// });
|
|
8
|
-
|
|
9
|
-
// // callback flow (nested, but correct)
|
|
10
|
-
// // auth.otp.generate(6, (err, code) => {
|
|
11
|
-
// // if (err) return console.error('generate err', err);
|
|
12
|
-
|
|
13
|
-
// // auth.otp.set('jahongir.sobirov.2007@mail.ru', (err) => {
|
|
14
|
-
// // if (err) return console.error('set err', err);
|
|
15
|
-
// // console.log('OTP stored in memory:', auth.otp.otpCode);
|
|
16
|
-
|
|
17
|
-
// // auth.otp.message({
|
|
18
|
-
// // to: 'jahongir.sobirov.2007@mail.ru',
|
|
19
|
-
// // subject: 'Your OTP',
|
|
20
|
-
// // text: `Your OTP is ${auth.otp.otpCode}`
|
|
21
|
-
// // }, (err, info) => {
|
|
22
|
-
// // if (err) return console.error('message err', err);
|
|
23
|
-
// // console.log('message sent ok', info && info.messageId);
|
|
24
|
-
|
|
25
|
-
// // // now verify
|
|
26
|
-
// // auth.otp.verify({ check: 'jahongir.sobirov.2007@mail.ru', code: "auth.otp.otpCode" }, (err, ok) => {
|
|
27
|
-
// // if (err){
|
|
28
|
-
// // // Resend OTP
|
|
29
|
-
// // auth.otp.resend("jahongir.sobirov.2007@mail.ru", (err, info) => {
|
|
30
|
-
// // if(err) return console.log("Resend failed:", err);
|
|
31
|
-
// // console.log("New OTP sent!");
|
|
32
|
-
// // });
|
|
33
|
-
// // };
|
|
34
|
-
|
|
35
|
-
// // console.log('Verified:', ok);
|
|
36
|
-
// // });
|
|
37
|
-
// // });
|
|
38
|
-
// // });
|
|
39
|
-
// // });
|
|
40
|
-
|
|
41
|
-
// // (async () => {
|
|
42
|
-
// // // try {
|
|
43
|
-
// // // 1️⃣ Generate OTP
|
|
44
|
-
// // auth.otp.generate(5).set('+998934313977'); // or auth.otp.code
|
|
45
|
-
// // // // 2️⃣ Store OTP
|
|
46
|
-
// // // await auth.otp.set('jahongir.sobirov.2007@mail.ru');
|
|
47
|
-
// // // console.log('OTP stored in memory:', auth.otp.code);
|
|
48
|
-
|
|
49
|
-
// // // // 3️⃣ Send OTP via email
|
|
50
|
-
// // // const info = await auth.otp.message({
|
|
51
|
-
// // // to: 'jahongir.sobirov.2007@mail.ru',
|
|
52
|
-
// // // subject: 'Your OTP',
|
|
53
|
-
// // // html: `Your OTP is ${auth.otp.code}`,
|
|
54
|
-
// // // });
|
|
55
|
-
// // // console.log('Message sent OK:', info && info.messageId);
|
|
56
|
-
|
|
57
|
-
// // // // 4️⃣ Verify OTP
|
|
58
|
-
// // // try {
|
|
59
|
-
// // // const verified = await auth.otp.verify({
|
|
60
|
-
// // // check: 'jahongir.sobirov.2007@mail.ru',
|
|
61
|
-
// // // code: '123456', // user's input
|
|
62
|
-
// // // });
|
|
63
|
-
// // // console.log('Verified:', verified);
|
|
64
|
-
// // // } catch (verifyErr) {
|
|
65
|
-
// // // console.log('Verification failed:', verifyErr.message);
|
|
66
|
-
|
|
67
|
-
// // // // 5️⃣ Resend OTP if verification fails
|
|
68
|
-
// // // try {
|
|
69
|
-
// // // const newCode = await auth.otp.resend('jahongir.sobirov.2007@mail.ru');
|
|
70
|
-
// // // console.log('New OTP sent:', newCode);
|
|
71
|
-
// // // } catch (resendErr) {
|
|
72
|
-
// // // console.log('Resend failed:', resendErr.message);
|
|
73
|
-
// // // }
|
|
74
|
-
// // // }
|
|
75
|
-
// // // } catch (err) {
|
|
76
|
-
// // // console.error('Error:', err);
|
|
77
|
-
// // // }
|
|
78
|
-
// // await auth.otp.message({
|
|
79
|
-
// // to: '+998934313977',
|
|
80
|
-
// // });
|
|
81
|
-
// // console.log(`OTP was sent`);
|
|
82
|
-
// // })();
|
|
83
|
-
|
|
84
|
-
// // Set custom logger
|
|
85
|
-
// auth.setLogger(console);
|
|
86
|
-
|
|
87
|
-
// // Access developer tools
|
|
88
|
-
// auth.dev.sender(async ({to, code})=>{
|
|
89
|
-
// const token = '6657700716:AAGW3s5Yxk5SrRH7yRqrgG-kVrG9a6PXBxk';
|
|
90
|
-
// const bot = new TelegramBot(token, {polling: false});
|
|
91
|
-
// bot.onText(/\/start/, async (msg)=>{
|
|
92
|
-
// const chatId = msg.chat.id;
|
|
93
|
-
// await bot.sendMessage(chatId, `🔐 Your verification code is: <b>${code}</b>`, {parse_mode: "HTML"})
|
|
94
|
-
// console.log(`✅ OTP ${code} sent to Telegram chat ${chatId}`);
|
|
95
|
-
// });
|
|
96
|
-
// });
|
|
97
|
-
|
|
98
|
-
// (async ()=>{
|
|
99
|
-
// try{
|
|
100
|
-
|
|
101
|
-
// }catch(err){}
|
|
102
|
-
// })();
|
|
103
|
-
|
|
104
|
-
// const TelegramBot = require("node-telegram-bot-api");
|
|
105
|
-
const express = require('express');
|
|
106
|
-
const AuthVerify = require("./index"); // your library
|
|
107
|
-
const app = express();
|
|
108
|
-
app.use(express.json());
|
|
109
|
-
// // Your bot token from BotFather
|
|
110
|
-
// const BOT_TOKEN = "6657700716:AAGW3s5Yxk5SrRH7yRqrgG-kVrG9a6PXBxk";
|
|
111
|
-
|
|
112
|
-
// // Step 1: Create a Telegram bot with polling enabled (to listen to /start)
|
|
113
|
-
// const bot = new TelegramBot(BOT_TOKEN, { polling: true });
|
|
114
|
-
|
|
115
|
-
// // Step 2: Create AuthVerify instance
|
|
116
|
-
// const auth = new AuthVerify({ jwtSecret: "super_secret_key" , storeTokens: 'memory'});
|
|
117
|
-
|
|
118
|
-
// // Step 3: Setup dev sender (so OTP messages are sent through Telegram)
|
|
119
|
-
// auth.dev.sender({
|
|
120
|
-
// send: async ({ to, code }) => {
|
|
121
|
-
// await bot.sendMessage(to, `🔑 Your OTP code is: ${code}`);
|
|
122
|
-
// },
|
|
123
|
-
// });
|
|
124
|
-
|
|
125
|
-
// // Step 4: When user sends /start, bot saves their chatId and sends an OTP
|
|
126
|
-
// bot.onText(/\/start/, async (msg) => {
|
|
127
|
-
// const chatId = msg.chat.id;
|
|
128
|
-
// const username = msg.from.username || msg.from.first_name;
|
|
129
|
-
|
|
130
|
-
// await bot.sendMessage(chatId, `👋 Hello ${username}! We'll send you an OTP now.`);
|
|
131
|
-
|
|
132
|
-
// // Generate and send OTP using auth.otp
|
|
133
|
-
// const otpCode = await auth.otp.generate(chatId); // you can customize
|
|
134
|
-
// await auth.otp.send(chatId); // uses our custom sender!
|
|
135
|
-
// });
|
|
136
|
-
|
|
137
|
-
// // Step 5: Listen for OTP input
|
|
138
|
-
// bot.on("message", async (msg) => {
|
|
139
|
-
// const chatId = msg.chat.id;
|
|
140
|
-
// const text = msg.text;
|
|
141
|
-
|
|
142
|
-
// // Ignore /start
|
|
143
|
-
// if (text.startsWith("/")) return;
|
|
144
|
-
|
|
145
|
-
// // Check if entered OTP is valid
|
|
146
|
-
// const isValid = await auth.otp.verify(chatId, text);
|
|
147
|
-
// if (isValid) {
|
|
148
|
-
// bot.sendMessage(chatId, "✅ OTP verified successfully!");
|
|
149
|
-
// } else {
|
|
150
|
-
// bot.sendMessage(chatId, "❌ Invalid or expired OTP. Try again!");
|
|
151
|
-
// }
|
|
152
|
-
// });
|
|
153
|
-
|
|
154
|
-
const auth = new AuthVerify({ jwtSecret: 's', storeTokens: 'memory'});
|
|
155
|
-
|
|
156
|
-
const google = auth.oauth.google({clientId: '145870939941-qgeskqo8qlaqqm1osed6f5r8bhl866qk.apps.googleusercontent.com', clientSecret: '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', redirectUri: 'http://localhost:3000/auth/google/callback'});
|
|
157
|
-
app.get('/', async (req, res) => {
|
|
158
|
-
res.send(`
|
|
159
|
-
<h1>Login with Google</h1>
|
|
160
|
-
<a href="/auth/google">Login</a>
|
|
161
|
-
`);
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
app.get('/auth/google', (req, res) => google.redirect(res));
|
|
166
|
-
|
|
167
|
-
app.get('/auth/google/callback', async (req, res)=>{
|
|
168
|
-
const code = req.query.code;
|
|
169
|
-
try {
|
|
170
|
-
const user = await google.callback(code);
|
|
171
|
-
res.send(`
|
|
172
|
-
<h2>Welcome, ${user.name}!</h2>
|
|
173
|
-
<img src="${user.picture}" width="100" style="border-radius:50%">
|
|
174
|
-
<p>Email: ${user.email}</p>
|
|
175
|
-
<p>Access Token: ${user.access_token.slice(0, 20)}...</p>
|
|
176
|
-
`);
|
|
177
|
-
} catch(err){
|
|
178
|
-
res.status(500).send("Error: " + err.message);
|
|
179
|
-
}
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
app.listen(3000, ()=>{
|
|
183
|
-
console.log('Server is running...');
|
|
184
|
-
});
|
|
185
|
-
// app.get('/verify', async (req, res) => {
|
|
186
|
-
// try {
|
|
187
|
-
// const data = await auth.jwt.verify({ headers: req.headers });
|
|
188
|
-
// res.json({ valid: true, data });
|
|
189
|
-
// } catch (err) {
|
|
190
|
-
// res.status(401).json({ valid: false, error: err.message });
|
|
191
|
-
// }
|
|
192
|
-
// });
|
|
193
|
-
|
|
194
|
-
// app.listen(3000, ()=>{
|
|
195
|
-
// console.log('App is running')
|
|
196
|
-
// });
|
|
197
|
-
|
|
198
|
-
// auth.register.sender("consoleOtp", async ({ to, code }) => {
|
|
199
|
-
// console.log(`🔑 Sending OTP ${code} to ${to}`);
|
|
200
|
-
// return true;
|
|
201
|
-
// });
|
|
202
|
-
|
|
203
|
-
// (async () => {
|
|
204
|
-
// await auth.use("consoleOtp").send({ to: "+998901234567", code: "654321" });
|
|
205
|
-
// })();
|