auth-verify 1.1.0 → 1.2.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/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  const JWTManager = require("./src/jwt");
2
2
  const OTPManager = require("./src/otp");
3
3
  const SessionManager = require("./src/session");
4
+ const OAuthManager = require("./src/oauth")
4
5
 
5
6
  class AuthVerify {
6
7
  constructor(options = {}) {
@@ -39,6 +40,8 @@ class AuthVerify {
39
40
  // }
40
41
  // }
41
42
  // ✅ No getters — directly reference otp.dev (it's a plain object)
43
+
44
+ this.oauth = new OAuthManager();
42
45
  }
43
46
 
44
47
  // Session helpers
package/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "uuid": "^13.0.0"
13
13
  },
14
14
  "name": "auth-verify",
15
- "version": "1.1.0",
15
+ "version": "1.2.0",
16
16
  "description": "A simple Node.js library for sending and verifying OTP via email",
17
17
  "main": "index.js",
18
18
  "scripts": {
package/readme.md CHANGED
@@ -1,17 +1,15 @@
1
1
  # auth-verify
2
2
 
3
3
  **auth-verify** is a Node.js authentication utility that provides:
4
- - Secure OTP (one-time password) generation and verification
5
- - Sending OTPs via Email, SMS (pluggable helpers), and Telegram bot
6
- - JWT creation, verification and optional token revocation with memory/Redis storage
7
- - Session management (in-memory or Redis)
8
- - Developer extensibility: custom senders and `auth.register.sender()` / `auth.use(name).send(...)`
9
-
10
- > This README documents the code structure and APIs found in the library files you provided (OTPManager, JWTManager, SessionManager, AuthVerify).
11
-
4
+ - Secure OTP (one-time password) generation and verification
5
+ - Sending OTPs via Email, SMS (pluggable helpers), and Telegram bot
6
+ - JWT creation, verification and optional token revocation with memory/Redis storage
7
+ - Session management (in-memory or Redis)
8
+ - New: OAuth 2.0 integration for Google, Facebook, GitHub, and X (Twitter)
9
+ - ⚙️ Developer extensibility: custom senders and `auth.register.sender()` / `auth.use(name).send(...)`
12
10
  ---
13
11
 
14
- ## Installation
12
+ ## 🧩 Installation
15
13
 
16
14
  ```bash
17
15
  # from npm (when published)
@@ -23,16 +21,16 @@ npm install auth-verify
23
21
 
24
22
  ---
25
23
 
26
- ## Quick overview
24
+ ## ⚙️ Quick overview
27
25
 
28
26
  - `AuthVerify` (entry): constructs and exposes `.jwt`, `.otp`, and (optionally) `.session` managers.
29
27
  - `JWTManager`: sign, verify, decode, revoke tokens. Supports `storeTokens: "memory" | "redis" | "none"`.
30
28
  - `OTPManager`: generate, store, send, verify, resend OTPs. Supports `storeTokens: "memory" | "redis" | "none"`. Supports email, SMS helper, Telegram bot, and custom dev senders.
31
29
  - `SessionManager`: simple session creation/verification/destroy with memory or Redis backend.
32
-
30
+ - `OAuthManager`: Handle OAuth 2.0 logins for Google, Facebook, GitHub, X
33
31
  ---
34
32
 
35
- ## Example: Initialize library (CommonJS)
33
+ ## 🚀 Example: Initialize library (CommonJS)
36
34
 
37
35
  ```js
38
36
  const AuthVerify = require('auth-verify');
@@ -48,7 +46,7 @@ const auth = new AuthVerify({
48
46
 
49
47
  ---
50
48
 
51
- ## JWT usage
49
+ ## 🔐 JWT Usage
52
50
 
53
51
  ```js
54
52
  // create JWT
@@ -71,7 +69,7 @@ await auth.jwt.revokeUntil(token, '10m');
71
69
  // check if token is revoked (returns boolean)
72
70
  const isRevoked = await auth.jwt.isRevoked(token);
73
71
  ```
74
- ## 🍪 Automatic Cookie Handling (New in v1.1.0)
72
+ ### 🍪 Automatic Cookie Handling (v1.1.0+)
75
73
 
76
74
  You can now automatically store and verify JWTs via HTTP cookies — no need to manually send them!
77
75
  ```js
@@ -111,9 +109,9 @@ Notes:
111
109
 
112
110
  ---
113
111
 
114
- ## OTP (email / sms / telegram / custom sender)
112
+ ## 🔢 OTP (email / sms / telegram / custom sender)
115
113
 
116
- ### Configure sender
114
+ ### 🤝 Configure sender
117
115
 
118
116
  You can set the default sender (email/sms/telegram):
119
117
 
@@ -145,7 +143,7 @@ auth.otp.setSender({
145
143
  });
146
144
  ```
147
145
 
148
- ### Generate → Save → Send (chainable)
146
+ ### ⛓️ Generate → Save → Send (chainable)
149
147
 
150
148
  OTP generation is chainable: `generate()` returns the OTP manager instance.
151
149
 
@@ -176,7 +174,7 @@ await auth.otp.message({
176
174
  });
177
175
  ```
178
176
 
179
- ### Verify
177
+ ### ✔️ Verify
180
178
 
181
179
  ```js
182
180
  // Promise style
@@ -198,6 +196,128 @@ try {
198
196
 
199
197
  `resend` returns the new code (promise style) or calls callback.
200
198
 
199
+ ---
200
+ ## 🌍 OAuth 2.0 Integration (New in v1.2.0)
201
+ `auth.oauth` supports login via Google, Facebook, GitHub, and X (Twitter).
202
+ ### Example (Google Login with Express)
203
+ ```js
204
+ const express = require('express');
205
+ const AuthVerify = require("auth-verify");
206
+ const app = express();
207
+ app.use(express.json());
208
+ const auth = new AuthVerify({ jwtSecret: 's', storeTokens: 'memory'});
209
+
210
+ const google = auth.oauth.google({clientId: 'YOUR_CLIENT_ID', clientSecret: 'YOUR_CLIENT_SECRET', redirectUri: 'http://localhost:3000/auth/google/callback'});
211
+ app.get('/', async (req, res) => {
212
+ res.send(`
213
+ <h1>Login with Google</h1>
214
+ <a href="/auth/google">Login</a>
215
+ `);
216
+ });
217
+
218
+
219
+ app.get('/auth/google', (req, res) => google.redirect(res));
220
+
221
+ app.get('/auth/google/callback', async (req, res)=>{
222
+ const code = req.query.code;
223
+ try {
224
+ const user = await google.callback(code);
225
+ res.send(`
226
+ <h2>Welcome, ${user.name}!</h2>
227
+ <img src="${user.picture}" width="100" style="border-radius:50%">
228
+ <p>Email: ${user.email}</p>
229
+ <p>Access Token: ${user.access_token.slice(0, 20)}...</p>
230
+ `);
231
+ } catch(err){
232
+ res.status(500).send("Error: " + err.message);
233
+ }
234
+ });
235
+
236
+ app.listen(3000, ()=>{
237
+ console.log('Server is running...');
238
+ });
239
+ ```
240
+ ---
241
+ ### API documentation for OAuth
242
+ - `auth.oauth.google({...})` for making connection to your Google cloud app.
243
+ - `google.redirect(res)` for sending user/client to the Google OAuth page for verifying and selecting his accaount
244
+ - `google.callback(code)` for exchanging server code to the user/client token.
245
+
246
+ ### Other examples with other platforms
247
+ ```js
248
+ const express = require('express');
249
+ const AuthVerify = require("auth-verify");
250
+ const app = express();
251
+ app.use(express.json());
252
+ const auth = new AuthVerify({ jwtSecret: 's', storeTokens: 'memory'});
253
+
254
+ // --- Example: FACEBOOK LOGIN ---
255
+ const facebook = auth.oauth.facebook({
256
+ clientId: "YOUR_FB_APP_ID",
257
+ clientSecret: "YOUR_FB_APP_SECRET",
258
+ redirectUri: "http://localhost:3000/auth/facebook/callback",
259
+ });
260
+
261
+ // --- Example: GITHUB LOGIN ---
262
+ const github = auth.oauth.github({
263
+ clientId: "YOUR_GITHUB_CLIENT_ID",
264
+ clientSecret: "YOUR_GITHUB_CLIENT_SECRET",
265
+ redirectUri: "http://localhost:3000/auth/github/callback",
266
+ });
267
+
268
+ // --- Example: X (Twitter) LOGIN ---
269
+ const twitter = auth.oauth.x({
270
+ clientId: "YOUR_TWITTER_CLIENT_ID",
271
+ clientSecret: "YOUR_TWITTER_CLIENT_SECRET",
272
+ redirectUri: "http://localhost:3000/auth/x/callback",
273
+ });
274
+
275
+
276
+ // ===== FACEBOOK ROUTES =====
277
+ app.get("/auth/facebook", (req, res) => facebook.redirect(res));
278
+
279
+ app.get("/auth/facebook/callback", async (req, res) => {
280
+ try {
281
+ const { code } = req.query;
282
+ const user = await facebook.callback(code);
283
+ res.json({ success: true, provider: "facebook", user });
284
+ } catch (err) {
285
+ res.status(400).json({ error: err.message });
286
+ }
287
+ });
288
+
289
+
290
+ // ===== GITHUB ROUTES =====
291
+ app.get("/auth/github", (req, res) => github.redirect(res));
292
+
293
+ app.get("/auth/github/callback", async (req, res) => {
294
+ try {
295
+ const { code } = req.query;
296
+ const user = await github.callback(code);
297
+ res.json({ success: true, provider: "github", user });
298
+ } catch (err) {
299
+ res.status(400).json({ error: err.message });
300
+ }
301
+ });
302
+
303
+
304
+ // ===== X (TWITTER) ROUTES =====
305
+ app.get("/auth/x", (req, res) => twitter.redirect(res));
306
+
307
+ app.get("/auth/x/callback", async (req, res) => {
308
+ try {
309
+ const { code } = req.query;
310
+ const user = await twitter.callback(code);
311
+ res.json({ success: true, provider: "x", user });
312
+ } catch (err) {
313
+ res.status(400).json({ error: err.message });
314
+ }
315
+ });
316
+
317
+
318
+ app.listen(PORT, () => console.log(`🚀 Server running at http://localhost:${PORT}`));
319
+
320
+ ```
201
321
  ---
202
322
 
203
323
  ## Telegram integration
@@ -281,9 +401,12 @@ auth-verify/
281
401
  ├─ package.json
282
402
  ├─ src/
283
403
  │ ├─ index.js // exports AuthVerify
284
- │ ├─ jwt.js
285
- ├─ otp.js
286
- ├─ session.js
404
+ │ ├─ jwt/
405
+ | | ├─ index.js
406
+ | | ├─ cookie/index.js
407
+ │ ├─ /otp/index.js
408
+ │ ├─ /session/index.js
409
+ | ├─ /oauth/index.js
287
410
  │ └─ helpers/helper.js
288
411
  ```
289
412
 
@@ -0,0 +1,180 @@
1
+ // src/managers/oauth.js
2
+
3
+ class OAuthManager {
4
+ constructor(config = {}) {
5
+ this.providers = config.providers || {};
6
+ }
7
+
8
+ // --- GOOGLE LOGIN ---
9
+ google({ clientId, clientSecret, redirectUri }) {
10
+ return {
11
+ redirect(res) {
12
+ const googleURL =
13
+ "https://accounts.google.com/o/oauth2/v2/auth?" +
14
+ new URLSearchParams({
15
+ client_id: clientId,
16
+ redirect_uri: redirectUri,
17
+ response_type: "code",
18
+ scope: "openid email profile",
19
+ access_type: "offline",
20
+ prompt: "consent",
21
+ });
22
+ res.redirect(googleURL);
23
+ },
24
+
25
+ async callback(code) {
26
+ // Step 1: Exchange code for access token
27
+ const tokenRes = await fetch("https://oauth2.googleapis.com/token", {
28
+ method: "POST",
29
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
30
+ body: new URLSearchParams({
31
+ client_id: clientId,
32
+ client_secret: clientSecret,
33
+ code,
34
+ redirect_uri: redirectUri,
35
+ grant_type: "authorization_code",
36
+ }),
37
+ });
38
+
39
+ const tokenData = await tokenRes.json();
40
+ if (tokenData.error) throw new Error("OAuth Error: " + tokenData.error);
41
+
42
+ // Step 2: Get user info
43
+ const userRes = await fetch("https://www.googleapis.com/oauth2/v2/userinfo", {
44
+ headers: { Authorization: `Bearer ${tokenData.access_token}` },
45
+ });
46
+ const user = await userRes.json();
47
+
48
+ return { ...user, access_token: tokenData.access_token };
49
+ },
50
+ };
51
+ }
52
+
53
+ // --- FACEBOOK LOGIN ---
54
+ facebook({ clientId, clientSecret, redirectUri }) {
55
+ return {
56
+ redirect(res) {
57
+ const fbURL =
58
+ "https://www.facebook.com/v19.0/dialog/oauth?" +
59
+ new URLSearchParams({
60
+ client_id: clientId,
61
+ redirect_uri: redirectUri,
62
+ scope: "email,public_profile",
63
+ response_type: "code",
64
+ });
65
+ res.redirect(fbURL);
66
+ },
67
+
68
+ async callback(code) {
69
+ const tokenRes = await fetch(
70
+ `https://graph.facebook.com/v19.0/oauth/access_token?` +
71
+ new URLSearchParams({
72
+ client_id: clientId,
73
+ client_secret: clientSecret,
74
+ redirect_uri: redirectUri,
75
+ code,
76
+ })
77
+ );
78
+
79
+ const tokenData = await tokenRes.json();
80
+ if (tokenData.error) throw new Error("OAuth Error: " + tokenData.error.message);
81
+
82
+ const userRes = await fetch(
83
+ `https://graph.facebook.com/me?fields=id,name,email,picture&access_token=${tokenData.access_token}`
84
+ );
85
+ const user = await userRes.json();
86
+
87
+ return { ...user, access_token: tokenData.access_token };
88
+ },
89
+ };
90
+ }
91
+
92
+ // --- GITHUB LOGIN ---
93
+ github({ clientId, clientSecret, redirectUri }) {
94
+ return {
95
+ redirect(res) {
96
+ const githubURL =
97
+ "https://github.com/login/oauth/authorize?" +
98
+ new URLSearchParams({
99
+ client_id: clientId,
100
+ redirect_uri: redirectUri,
101
+ scope: "user:email",
102
+ allow_signup: "true",
103
+ });
104
+ res.redirect(githubURL);
105
+ },
106
+
107
+ async callback(code) {
108
+ const tokenRes = await fetch("https://github.com/login/oauth/access_token", {
109
+ method: "POST",
110
+ headers: { "Content-Type": "application/json", Accept: "application/json" },
111
+ body: JSON.stringify({
112
+ client_id: clientId,
113
+ client_secret: clientSecret,
114
+ code,
115
+ redirect_uri: redirectUri,
116
+ }),
117
+ });
118
+
119
+ const tokenData = await tokenRes.json();
120
+ if (tokenData.error) throw new Error("OAuth Error: " + tokenData.error);
121
+
122
+ const userRes = await fetch("https://api.github.com/user", {
123
+ headers: { Authorization: `Bearer ${tokenData.access_token}` },
124
+ });
125
+ const user = await userRes.json();
126
+
127
+ return { ...user, access_token: tokenData.access_token };
128
+ },
129
+ };
130
+ }
131
+
132
+ // --- X (TWITTER) LOGIN ---
133
+ x({ clientId, clientSecret, redirectUri }) {
134
+ return {
135
+ redirect(res) {
136
+ const twitterURL =
137
+ "https://twitter.com/i/oauth2/authorize?" +
138
+ new URLSearchParams({
139
+ response_type: "code",
140
+ client_id: clientId,
141
+ redirect_uri: redirectUri,
142
+ scope: "tweet.read users.read offline.access",
143
+ state: "state123",
144
+ code_challenge: "challenge",
145
+ code_challenge_method: "plain",
146
+ });
147
+ res.redirect(twitterURL);
148
+ },
149
+
150
+ async callback(code) {
151
+ const tokenRes = await fetch("https://api.twitter.com/2/oauth2/token", {
152
+ method: "POST",
153
+ headers: {
154
+ "Content-Type": "application/x-www-form-urlencoded",
155
+ Authorization:
156
+ "Basic " + Buffer.from(`${clientId}:${clientSecret}`).toString("base64"),
157
+ },
158
+ body: new URLSearchParams({
159
+ code,
160
+ grant_type: "authorization_code",
161
+ redirect_uri: redirectUri,
162
+ code_verifier: "challenge",
163
+ }),
164
+ });
165
+
166
+ const tokenData = await tokenRes.json();
167
+ if (tokenData.error) throw new Error("OAuth Error: " + tokenData.error);
168
+
169
+ const userRes = await fetch("https://api.twitter.com/2/users/me", {
170
+ headers: { Authorization: `Bearer ${tokenData.access_token}` },
171
+ });
172
+ const user = await userRes.json();
173
+
174
+ return { ...user, access_token: tokenData.access_token };
175
+ },
176
+ };
177
+ }
178
+ }
179
+
180
+ module.exports = OAuthManager;
package/test.js CHANGED
@@ -153,23 +153,47 @@ app.use(express.json());
153
153
 
154
154
  const auth = new AuthVerify({ jwtSecret: 's', storeTokens: 'memory'});
155
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'});
156
157
  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!`);
158
+ res.send(`
159
+ <h1>Login with Google</h1>
160
+ <a href="/auth/google">Login</a>
161
+ `);
159
162
  });
160
163
 
161
- app.get('/verify', async (req, res) => {
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;
162
169
  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 });
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);
167
179
  }
168
180
  });
169
181
 
170
182
  app.listen(3000, ()=>{
171
- console.log('App is running')
183
+ console.log('Server is running...');
172
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
+ // });
173
197
 
174
198
  // auth.register.sender("consoleOtp", async ({ to, code }) => {
175
199
  // console.log(`🔑 Sending OTP ${code} to ${to}`);