auth-verify 0.0.2 → 1.1.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.
@@ -0,0 +1,81 @@
1
+ const Redis = require("ioredis");
2
+ const { v4: uuidv4 } = require("uuid");
3
+
4
+ class SessionManager {
5
+ constructor(options = {}) {
6
+ this.storeType = options.storeTokens || 'memory'; // 'memory' or 'redis'
7
+
8
+ if (this.storeType === 'memory') {
9
+ this.sessions = new Map();
10
+ } else if (this.storeType === 'redis') {
11
+ this.redis = new Redis(options.redisUrl || "redis://localhost:6379");
12
+ } else {
13
+ throw new Error("{storeTokens} should be 'memory' or 'redis'");
14
+ }
15
+ }
16
+
17
+ // Create a session
18
+ async create(userId, options = {}) {
19
+ const sessionId = uuidv4();
20
+ const expiresIn = options.expiresIn || 3600; // default 1 hour
21
+ if (typeof expiresIn === "string") {
22
+ const timeValue = parseInt(expiresIn);
23
+ if (expiresIn.endsWith("s")) expiresIn = timeValue;
24
+ else if (expiresIn.endsWith("m")) expiresIn = timeValue * 60;
25
+ else if (expiresIn.endsWith("h")) expiresIn = timeValue * 60 * 60;
26
+ else if (expiresIn.endsWith("d")) expiresIn = timeValue * 60 * 60 * 24;
27
+ else throw new Error("Invalid expiresIn format (use s, m, h, d)");
28
+ }
29
+ const now = Date.now();
30
+
31
+ const sessionData = {
32
+ userId,
33
+ createdAt: now,
34
+ expiresAt: now + expiresIn * 1000
35
+ };
36
+
37
+ if (this.storeType === 'memory') {
38
+ this.sessions.set(sessionId, sessionData);
39
+ } else if (this.storeType === 'redis') {
40
+ await this.redis.set(
41
+ sessionId,
42
+ JSON.stringify(sessionData),
43
+ "EX",
44
+ expiresIn
45
+ );
46
+ }
47
+
48
+ return sessionId;
49
+ }
50
+
51
+ // Verify a session
52
+ async verify(sessionId) {
53
+ let data;
54
+ if (this.storeType === 'memory') {
55
+ data = this.sessions.get(sessionId);
56
+ } else if (this.storeType === 'redis') {
57
+ const raw = await this.redis.get(sessionId);
58
+ data = raw ? JSON.parse(raw) : null;
59
+ }
60
+
61
+ if (!data) throw new Error("Session not found or expired");
62
+
63
+ if (Date.now() > data.expiresAt) {
64
+ await this.destroy(sessionId);
65
+ throw new Error("Session expired");
66
+ }
67
+
68
+ return data.userId;
69
+ }
70
+
71
+ // Destroy a session
72
+ async destroy(sessionId) {
73
+ if (this.storeType === 'memory') {
74
+ this.sessions.delete(sessionId);
75
+ } else if (this.storeType === 'redis') {
76
+ await this.redis.del(sessionId);
77
+ }
78
+ }
79
+ }
80
+
81
+ module.exports = SessionManager;
package/test.js CHANGED
@@ -1,34 +1,181 @@
1
- const Verifier = require("./Verifier"); // or "./index.js" if you renamed it
2
-
3
- const verifier = new Verifier({
4
- serv: "Gmail",
5
- sender: "your_email@gmail.com",
6
- pass: "your_app_password",
7
- otp: {
8
- length: 6,
9
- expMin: 5,
10
- limit: 5,
11
- cooldown: 60
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
+ app.get('/', async (req, res) => {
157
+ const token = await auth.jwt.sign({ id: 1, role: 'user' }, '1h', { res });
158
+ res.send(`JWT saved in cookie!`);
159
+ });
160
+
161
+ app.get('/verify', async (req, res) => {
162
+ try {
163
+ const data = await auth.jwt.verify({ headers: req.headers });
164
+ res.json({ valid: true, data });
165
+ } catch (err) {
166
+ res.status(401).json({ valid: false, error: err.message });
12
167
  }
13
168
  });
14
169
 
15
- // Test sending OTP
16
- verifier
17
- .subject("Your OTP: {otp}")
18
- .text("Your OTP code is {otp}")
19
- .html("<h1>{otp}</h1>")
20
- .sendTo("test_user@example.com", (err, success) => {
21
- if (err) return console.error("Send failed:", err.message);
22
- console.log("✅ OTP sent successfully!");
23
-
24
- // Test verifying the same OTP
25
- verifier.getOTP("test_user@example.com", (err, data) => {
26
- if (err) return console.error(err);
27
- console.log("Current OTP in DB:", data);
28
-
29
- verifier.code(data.code).verifyFor("test_user@example.com", (err, verified) => {
30
- if (err) return console.error(err);
31
- console.log("Verified?", verified);
32
- });
33
- });
34
- });
170
+ app.listen(3000, ()=>{
171
+ console.log('App is running')
172
+ });
173
+
174
+ // auth.register.sender("consoleOtp", async ({ to, code }) => {
175
+ // console.log(`🔑 Sending OTP ${code} to ${to}`);
176
+ // return true;
177
+ // });
178
+
179
+ // (async () => {
180
+ // await auth.use("consoleOtp").send({ to: "+998901234567", code: "654321" });
181
+ // })();
package/auth-verify.js DELETED
@@ -1,182 +0,0 @@
1
- const sqlite3 = require("sqlite3").verbose();
2
- const nodemailer = require('nodemailer')
3
- const crypto = require('crypto');
4
- const { request } = require("http");
5
-
6
- class Verifier {
7
- constructor(sender = {}){
8
- this.otpLen = sender.otp?.leng || 6;
9
- this.expMin = sender.otp?.expMin || 3;
10
- this.limit = sender.otp?.limit || 5;
11
- this.cooldown = sender.otp?.cooldown || 60;
12
- // Setup SMTP
13
- this.transport = nodemailer.createTransport({
14
- service: `${sender.serv}`,
15
- auth: {
16
- user: `${sender.sender}`,
17
- pass: sender.pass
18
- }
19
- });
20
-
21
- this.sender = `${sender.smtp?.sender}`
22
-
23
- //making a db for saving otp codes
24
- this.db = new sqlite3.Database('./authverify.db');
25
- this.db.serialize(()=>{
26
- // creating a table
27
- this.db.run(`
28
- CREATE TABLE IF NOT EXISTS verifications (
29
- email TEXT PRIMARY KEY,
30
- code TEXT,
31
- expiresAt TEXT,
32
- requests INTEGER DEFAULT 0,
33
- lastRequest TEXT
34
- )
35
- `);
36
- });
37
-
38
- }
39
-
40
- // Generate OTP securely
41
- generateOTP() {
42
- const buffer = crypto.randomBytes(this.otpLen);
43
- const number = parseInt(buffer.toString('hex'), 16)
44
- .toString()
45
- .slice(0, this.otpLen);
46
- return number.padStart(this.otpLen, '0');
47
- }
48
-
49
- html(html){
50
- this.htmlContent = html;
51
- return this;
52
- }
53
-
54
- subject(subject){
55
- this.mailSubject = subject;
56
- return this;
57
- }
58
-
59
- text(text){
60
- this.mailText = text;
61
- return this;
62
- }
63
-
64
- sendTo(email, callback){
65
-
66
- this.recieverEmail = email;
67
- const code = this.generateOTP();
68
- const expAt = new Date(Date.now() + this.expMin * 60 * 1000).toISOString();
69
-
70
- this.db.get(`SELECT * FROM verifications WHERE email = ?`, [email], (err, row)=>{
71
- if(err) return callback(err);
72
-
73
- const now = new Date();
74
- let requests = 1;
75
-
76
- if(row){
77
- const lastRequest = row.lastRequest ? new Date(row.lastRequest) : null;
78
-
79
- if(lastRequest && now.toDateString() === lastRequest.toDateString()){
80
- requests = row.requests + 1;
81
- if(requests > this.limit){
82
- return callback(new Error("Too many OTP requests today"));
83
- }
84
-
85
- const diff = (now - lastRequest) / 1000;
86
- if(diff < this.cooldown){
87
- return callback(new Error(`Please wait ${Math.ceil(this.cooldown - diff)} seconds before requesting a new OTP.`));
88
- }
89
- }
90
- }
91
-
92
- this.db.run(`INSERT INTO verifications (email, code, expiresAt, requests, lastRequest) VALUES (?, ?, ?, ?, ?)
93
- ON CONFLICT(email) DO UPDATE SET
94
- code = excluded.code,
95
- expiresAt = excluded.expiresAt,
96
- requests = excluded.requests,
97
- lastRequest = excluded.lastRequest`, [email, code, expAt, requests, now.toISOString()], (DBerr)=>{
98
- if(DBerr) return callback(DBerr);
99
-
100
- this.otpOptions = {
101
- from: this.sender,
102
- to: `${email}`,
103
- subject: this.mailSubject ? this.mailSubject.replace("{otp}", code) : undefined,
104
- text: this.mailText ? this.mailText.replace("{otp}", code) : undefined,
105
- html: this.htmlContent ? this.htmlContent.replace("{otp}", code) : undefined
106
- }
107
-
108
- this.transport.sendMail(this.otpOptions, (emailErr, info)=>{
109
- if(emailErr) return callback(emailErr);
110
-
111
- // console.log('📨 Email sent:', info.response);
112
- callback(null, true);
113
- });
114
-
115
- // console.log('💾 Code saved to DB');
116
- });
117
- });
118
-
119
- return this;
120
-
121
- }
122
-
123
- code(userCode){
124
- this.userCode = userCode
125
- return this;
126
- }
127
-
128
- verifyFor(email, callback){
129
- const now = new Date().toISOString();
130
-
131
- this.db.get(`SELECT * FROM verifications WHERE email = ? AND expiresAt > ?`, [email, now], (DBerr, row)=>{
132
- if(DBerr) return callback(DBerr);
133
-
134
- // console.log(`Code was got`);
135
-
136
- if(!row){
137
- // console.log(this.recieverEmail);
138
- callback(null, false)
139
- }else{
140
- if(row.code === this.userCode){
141
- // console.log('✅ User verified');
142
- callback(null, true);
143
- }else{
144
- // console.log("❌ Code isn't correct")
145
- callback(null, false);
146
- }
147
- }
148
- });
149
- }
150
-
151
- makeOTP(length){
152
- const buffer = crypto.randomBytes(length);
153
- const number = parseInt(buffer.toString('hex'), 16)
154
- .toString()
155
- .slice(0, length);
156
- return number.padStart(length, '0');
157
- }
158
-
159
- getOTP(email, callback){
160
- this.db.get(`SELECT * FROM verifications WHERE email = ?`, [email], (err, row)=>{
161
- if(err) return callback(err);
162
- if(!row) return callback(null, null);
163
-
164
- callback(null, { code: row.code, expiresAt: row.expiresAt });
165
- });
166
- }
167
-
168
- cleanExpired() {
169
- const now = new Date().toISOString();
170
- this.db.run(
171
- `DELETE FROM verifications WHERE expiresAt <= ?`,
172
- [now],
173
- function(err) {
174
- if (err) console.error("Error cleaning expired OTPs:", err.message);
175
- // Optional: console.log(`${this.changes} expired OTPs removed`);
176
- }
177
- );
178
- }
179
-
180
- }
181
-
182
- module.exports = Verifier;
package/authverify.db DELETED
Binary file
package/otp.db DELETED
Binary file