auth-verify 1.10.0 → 1.11.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.
@@ -80,97 +80,6 @@ window.AuthVerify = class AuthVerify {
80
80
  return new Uint8Array([...str].map(c => c.charCodeAt(0)));
81
81
  }
82
82
 
83
- // start(route){
84
- // this.startRegisterApi = route;
85
- // return this;
86
- // }
87
-
88
- // finish(route){
89
- // this.finishRegisterApi = route;
90
- // return this;
91
- // }
92
-
93
- // // -----------------------------
94
- // // REGISTER PASSKEY (full flow)
95
- // // -----------------------------
96
- // async registerPasskey(user) {
97
- // try {
98
- // // 1️⃣ Get registration options from backend
99
- // const publicKey = await this.post(`${this.startRegisterApi}`).data({user});
100
-
101
- // // 2️⃣ Decode challenge & user.id automatically
102
- // publicKey.challenge = this.base64urlToUint8Array(publicKey.challenge);
103
- // publicKey.user.id = this.base64urlToUint8Array(publicKey.user.id);
104
-
105
- // // 3️⃣ Ask browser to create credential
106
- // const credential = await navigator.credentials.create({ publicKey });
107
-
108
- // // 4️⃣ Convert ArrayBuffers to base64
109
- // const data = {
110
- // id: credential.id,
111
- // rawId: btoa(String.fromCharCode(...new Uint8Array(credential.rawId))),
112
- // type: credential.type,
113
- // response: {
114
- // clientDataJSON: btoa(String.fromCharCode(...new Uint8Array(credential.response.clientDataJSON))),
115
- // attestationObject: btoa(String.fromCharCode(...new Uint8Array(credential.response.attestationObject))),
116
- // },
117
- // };
118
-
119
- // // 5️⃣ Send credential to backend to finish registration
120
- // const result = await this.post(`${this.finishRegisterApi}`).data(data);
121
-
122
- // return result;
123
-
124
- // } catch (err) {
125
- // console.error("[AuthVerify registerPasskey]", err);
126
- // return { error: true, message: err.message };
127
- // }
128
- // }
129
-
130
- // // -----------------------------
131
- // // LOGIN / AUTHENTICATE PASSKEY
132
- // // -----------------------------
133
- // async loginPasskey(user) {
134
- // try {
135
- // // 1️⃣ Get assertion options (challenge) from backend
136
- // const publicKey = await this.post(`${this.startRegisterApi}`).data({ user, login: true });
137
-
138
- // // 2️⃣ Decode Base64URL fields
139
- // publicKey.challenge = this.base64urlToUint8Array(publicKey.challenge);
140
- // publicKey.allowCredentials = publicKey.allowCredentials.map(cred => ({
141
- // ...cred,
142
- // id: this.base64urlToUint8Array(cred.id)
143
- // }));
144
-
145
- // // 3️⃣ Ask browser to get credential
146
- // const credential = await navigator.credentials.get({ publicKey });
147
-
148
- // // 4️⃣ Convert ArrayBuffers to Base64
149
- // const data = {
150
- // id: credential.id,
151
- // rawId: btoa(String.fromCharCode(...new Uint8Array(credential.rawId))),
152
- // type: credential.type,
153
- // response: {
154
- // clientDataJSON: btoa(String.fromCharCode(...new Uint8Array(credential.response.clientDataJSON))),
155
- // authenticatorData: btoa(String.fromCharCode(...new Uint8Array(credential.response.authenticatorData))),
156
- // signature: btoa(String.fromCharCode(...new Uint8Array(credential.response.signature))),
157
- // userHandle: credential.response.userHandle
158
- // ? btoa(String.fromCharCode(...new Uint8Array(credential.response.userHandle)))
159
- // : null,
160
- // },
161
- // };
162
-
163
- // // 5️⃣ Send assertion to backend for verification
164
- // const result = await this.post(`${this.finishRegisterApi}`).data(data);
165
-
166
- // return result;
167
-
168
- // } catch (err) {
169
- // console.error("[AuthVerify loginPasskey]", err);
170
- // return { error: true, message: err.message };
171
- // }
172
- // }
173
-
174
83
  async issue(publicKey){
175
84
  publicKey.challenge = this.base64urlToUint8Array(publicKey.challenge);
176
85
  publicKey.user.id = this.base64urlToUint8Array(publicKey.user.id);
package/package.json CHANGED
@@ -3,20 +3,24 @@
3
3
  "axios": "^1.12.2",
4
4
  "base64url": "^3.0.1",
5
5
  "cbor": "^10.0.11",
6
+ "cors": "^2.8.5",
6
7
  "crypto": "^1.0.1",
8
+ "express": "^5.1.0",
7
9
  "ioredis": "^5.8.1",
8
10
  "jsonwebtoken": "^9.0.2",
9
11
  "node-telegram-bot-api": "^0.66.0",
10
12
  "nodemailer": "^7.0.6",
13
+ "path": "^0.12.7",
11
14
  "qrcode": "^1.5.4",
12
15
  "uuid": "^9.0.1"
13
16
  },
14
17
  "name": "auth-verify",
15
- "version": "1.10.0",
18
+ "version": "1.11.0",
16
19
  "description": "A simple Node.js library for sending and verifying OTP via email, SMS and Telegram bot. And generating TOTP codes and QR codes. And handling JWT with Cookies. And also handling passwordless logins with passkeys/webauth. And handling magiclink passwordless logins",
17
20
  "main": "index.js",
18
21
  "scripts": {
19
- "test": "jest --runInBand"
22
+ "test": "jest --runInBand",
23
+ "start:api": "node rest-api/index.js"
20
24
  },
21
25
  "repository": {
22
26
  "type": "git",
@@ -51,7 +55,9 @@
51
55
  "passwordless",
52
56
  "magiclink",
53
57
  "hash",
54
- "password_hashing"
58
+ "password_hashing",
59
+ "api",
60
+ "rest-api"
55
61
  ],
56
62
  "author": "Jahongir Sobirov",
57
63
  "license": "MIT",
package/readme.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # auth-verify
2
2
 
3
- **AuthVerify** is a modular authentication library for Node.js, providing JWT, OTP, TOTP, Passkeys (WebAuthn), Magic Links, Sessions, and OAuth helpers. You can easily register custom senders for OTPs or notifications.
3
+ **AuthVerify** is a modular authentication library for Node.js, providing JWT, OTP, TOTP, Passkeys (WebAuthn), Magic Links, Sessions, and OAuth helpers. You can easily register custom senders for OTPs or notifications. Auth-verify now supports **REST API** for generating, sending OTP with email/SMS and verifying it.
4
4
  - [Installation](https://github.com/Jahongir2007/auth-verify/blob/main/docs/docs.md#-installation)
5
5
  - [Initialization](https://github.com/Jahongir2007/auth-verify/blob/main/docs/docs.md#-example-initialize-library-commonjs)
6
6
  - [JWT](https://github.com/Jahongir2007/auth-verify/blob/main/docs/docs.md#-jwt-usage)
@@ -13,6 +13,7 @@
13
13
  - [Custom Senders](https://github.com/Jahongir2007/auth-verify/blob/main/docs/docs.md#developer-extensibility-custom-senders)
14
14
  - [Session Management](https://github.com/Jahongir2007/auth-verify/blob/main/docs/docs.md#-sessionmanager-api-documentation---auth-verify)
15
15
  - [Crypto hashing](https://github.com/Jahongir2007/auth-verify/blob/main/docs/docs.md#-cryptomanager-api-guide)
16
+ - [Auth-verify REST API](https://auth-verify-sy2y.onrender.com/)
16
17
  ---
17
18
 
18
19
  ## 🧩 Installation
@@ -34,9 +35,10 @@ npm install auth-verify
34
35
  - `OTPManager`: generate, store, send, verify, resend OTPs. Supports `storeTokens: "memory" | "redis" | "none"`. Supports email, SMS helper, Telegram bot, and custom dev senders.
35
36
  - `TOTPManager`: generate, verify uri, codes and QR codes.
36
37
  - `SessionManager`: simple session creation/verification/destroy with memory or Redis backend.
37
- - `OAuthManager`: Handle OAuth 2.0 logins for Google, Facebook, GitHub, X, Linkedin, Apple, Discord, Slack, Microsoft, Telegram and WhatsApp.
38
+ - `OAuthManager`: Handle OAuth 2.0 logins for 20+ providers.
38
39
  - `PasskeyManager`: Handle passwordless login and registration using WebAuthn/passkey.
39
40
  - `MagicLinkManager`: Handle passwordless login with magic link generation and verification.
41
+ - `CrpytoManager`: Handle hashing passwords or another data with algorithms like: `"pbkdf2"` and `"scrypt"`
40
42
  ---
41
43
 
42
44
  ## 🚀 Example: Initialize library (CommonJS)
@@ -316,6 +318,7 @@ const otp = auth.otp; // internally uses OTPManager
316
318
 
317
319
  ### ⚙️ Sender Configuration
318
320
  #### Email sender
321
+ ##### Using Gmail
319
322
  ```js
320
323
  otp.sender({
321
324
  via: "email", // or "sms", "telegram", "whatsapp"
@@ -329,6 +332,17 @@ otp.sender({
329
332
 
330
333
  // or you can use otp.setSender({...});
331
334
  ```
335
+ ##### Using SMTP service
336
+ ```js
337
+ otp.sender({
338
+ via: "email", // or "sms", "telegram", "whatsapp"
339
+ sender: "your_email@gmail.com",
340
+ pass: "your_app_password",
341
+ host: "smtp.gmail.com",
342
+ port: 587,
343
+ secure: false
344
+ })
345
+ ```
332
346
  #### SMS sender
333
347
  ##### Using infobip:
334
348
  ```js
@@ -412,6 +426,9 @@ await otp.send("user@example.com", {
412
426
  text: "Your OTP is 123456",
413
427
  html: "<b>123456</b>"
414
428
  });
429
+
430
+ // or simply
431
+ await otp.send("user@example.com");
415
432
  ```
416
433
  Supports channels:
417
434
  | `via` | Notes |
@@ -432,10 +449,11 @@ otp.send("user@example.com", options, (err, info) => {
432
449
  ### 🔑 Verify OTP
433
450
  ```js
434
451
  // Promise style
435
- const result = await otp.verify({ check: "user@example.com", code: "123456" });
452
+ const result = await otp.verify("user@example.com", "123456");
453
+ //const result = await otp.verify({ check: "user@example.com", code: "123456" }); or you can use this style
436
454
 
437
455
  // Callback style
438
- otp.verify({ check: "user@example.com", code: "123456" }, (err, success) => {
456
+ otp.verify("user@example.com", "123456", (err, success) => {
439
457
  if(err) console.error(err.message);
440
458
  else console.log("✅ OTP verified");
441
459
  });
@@ -1737,16 +1755,9 @@ auth-verify/
1737
1755
  │ ├─ /session/index.js
1738
1756
  | ├─ /oauth/index.js
1739
1757
  │ └─ helpers/helper.js
1740
- ├─ tests/
1741
- │ ├─ jwa.test.js
1742
- │ ├─ cryptomanager.test.js
1743
- │ ├─ jwtmanager.multitab.test.js
1744
- │ ├─ jwtmanager.test.js
1745
- │ ├─ otpmanager.test.js
1746
- │ ├─ oauth.test.js
1747
- │ ├─ totpmanager.test.js
1748
- │ ├─ passkeymanager.test.js
1749
- │ ├─ magiclinkmanager.test.js
1758
+ ├─ rest-api/
1759
+ │ ├─ public/index.html
1760
+ │ ├─ index.js
1750
1761
  ├─ babel.config.js
1751
1762
  ├─ auth-verify.client.js
1752
1763
  ```
@@ -0,0 +1,171 @@
1
+ const express = require("express");
2
+ const cors = require("cors");
3
+ const AuthVerify = require("../index");
4
+ const path = require("path");
5
+
6
+ const app = express();
7
+ app.use(cors());
8
+ app.use(express.json());
9
+ app.use(express.static("public"));
10
+
11
+ const router = express.Router(); // FIXED
12
+
13
+ const auth = new AuthVerify();
14
+
15
+ // If user enters any route ("/", "/docs", etc) send homepage
16
+ app.get("/", (req, res) => {
17
+ res.sendFile(path.join(__dirname, "public/index.html"));
18
+ });
19
+
20
+ // Generating OTP (just generate code, no sending)
21
+ router.post('/auth/otp/generate/:leng', async (req, res) => {
22
+ try {
23
+ let { leng } = req.params;
24
+ const length = leng ? parseInt(leng) : 6; // default 6 digits if undefined
25
+
26
+ const otp = auth.otp.generate(length);
27
+
28
+ return res.json({
29
+ ok: true,
30
+ code: otp.code,
31
+ length
32
+ });
33
+ } catch (err) {
34
+ console.error(err);
35
+ return res.status(500).json({ ok: false, error: "Failed to generate OTP", message: err.message });
36
+ }
37
+ });
38
+
39
+
40
+ // ----------- Gmail Provider -------------
41
+ router.post('/auth/otp/send/gmail/:to', async (req, res) => {
42
+ try {
43
+ const { to } = req.params;
44
+ const { email, pass, subject, text, html } = req.body.sender || {};
45
+
46
+ if (!email || !pass) {
47
+ return res.status(400).json({ error: "Missing sender email or password" });
48
+ }
49
+
50
+ auth.otp.sender({
51
+ via: 'email',
52
+ service: 'gmail',
53
+ sender: email,
54
+ pass
55
+ });
56
+
57
+ const info = await auth.otp.send(to, {
58
+ subject: subject || "Your OTP Code",
59
+ text: text || "",
60
+ html: html || ""
61
+ });
62
+
63
+ return res.json({
64
+ ok: true,
65
+ provider: "gmail",
66
+ to
67
+ });
68
+
69
+ } catch (err) {
70
+ console.error(err);
71
+ return res.status(500).json({ error: "Failed to send OTP" });
72
+ }
73
+ });
74
+
75
+ // ----------- SMTP Provider -------------
76
+ router.post('/auth/otp/send/email/:to', async (req, res) => {
77
+ try {
78
+ const { to } = req.params;
79
+ const { email, pass, host, port, secure, subject, text, html } = req.body.sender || {};
80
+
81
+ if (!email || !pass || !host || !port) {
82
+ return res.status(400).json({ error: "Missing sender email or pass or host or port" });
83
+ }
84
+
85
+ auth.otp.sender({
86
+ via: 'email',
87
+ host,
88
+ port,
89
+ secure: secure || false,
90
+ sender: email,
91
+ pass
92
+ });
93
+
94
+ const info = await auth.otp.send(to, {
95
+ subject: subject || "Your OTP Code",
96
+ text: text || "",
97
+ html: html || ""
98
+ });
99
+
100
+ return res.json({
101
+ ok: true,
102
+ provider: "smtp",
103
+ to
104
+ });
105
+
106
+ } catch (err) {
107
+ console.error(err);
108
+ return res.status(500).json({ error: "Failed to send OTP" });
109
+ }
110
+ });
111
+
112
+ // ------ OTP SMS -------
113
+ router.post('/auth/otp/send/sms/:to', async (req, res)=>{
114
+ try {
115
+ const { to } = req.params;
116
+ const { provider, apiKey, apiSecret, sender, text } = req.body.sender || {};
117
+
118
+ if(!provider || !apiKey || !apiSecret || !sender) return res.status(400).json({error: "Missing sender provider or apiKey or apiSecret or sender"});
119
+
120
+ auth.otp.sender({
121
+ via: 'sms',
122
+ provider,
123
+ apiKey,
124
+ apiSecret,
125
+ sender
126
+ });
127
+
128
+ const info = await auth.otp.send(to, {text});
129
+
130
+ return res.json({
131
+ ok: true,
132
+ provider,
133
+ to
134
+ });
135
+ } catch(err){
136
+ console.error(err);
137
+ return res.status(500).json({ error: "Failed to send OTP with SMS" });
138
+ }
139
+ });
140
+
141
+ // Verify OTP sent by email
142
+ router.post('/auth/otp/verify/:to', async (req, res) => {
143
+ try {
144
+ const { to } = req.params;
145
+ const { otp } = req.body;
146
+
147
+ if (!otp) {
148
+ return res.status(400).json({ success: false, message: "Missing OTP code" });
149
+ }
150
+
151
+ const valid = await auth.otp.verify(to, otp);
152
+
153
+ if (valid) {
154
+ return res.status(200).json({ success: true, message: "OTP verified", to });
155
+ } else {
156
+ return res.status(400).json({ success: false, message: "OTP is incorrect", to });
157
+ }
158
+
159
+ } catch (err) {
160
+ console.error(err);
161
+ return res.status(500).json({ success: false, message: "Failed to verify OTP", error: err.message });
162
+ }
163
+ });
164
+
165
+
166
+ // mount router
167
+ app.use("/api", router); // IMPORTANT!!
168
+
169
+ app.listen(3000, () => {
170
+ console.log("REST API running on port 3000");
171
+ });