auth-verify 1.2.0 → 1.2.2

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/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "uuid": "^13.0.0"
13
13
  },
14
14
  "name": "auth-verify",
15
- "version": "1.2.0",
15
+ "version": "1.2.2",
16
16
  "description": "A simple Node.js library for sending and verifying OTP via email",
17
17
  "main": "index.js",
18
18
  "scripts": {
@@ -37,7 +37,8 @@
37
37
  "two-factor",
38
38
  "2fa",
39
39
  "email",
40
- "jwt"
40
+ "jwt",
41
+ "oauth"
41
42
  ],
42
43
  "author": "Jahongir Sobirov",
43
44
  "license": "MIT",
package/readme.md CHANGED
@@ -23,11 +23,11 @@ npm install auth-verify
23
23
 
24
24
  ## ⚙️ Quick overview
25
25
 
26
- - `AuthVerify` (entry): constructs and exposes `.jwt`, `.otp`, and (optionally) `.session` managers.
26
+ - `AuthVerify` (entry): constructs and exposes `.jwt`, `.otp`, (optionally) `.session` and `.oauth` managers.
27
27
  - `JWTManager`: sign, verify, decode, revoke tokens. Supports `storeTokens: "memory" | "redis" | "none"`.
28
28
  - `OTPManager`: generate, store, send, verify, resend OTPs. Supports `storeTokens: "memory" | "redis" | "none"`. Supports email, SMS helper, Telegram bot, and custom dev senders.
29
29
  - `SessionManager`: simple session creation/verification/destroy with memory or Redis backend.
30
- - `OAuthManager`: Handle OAuth 2.0 logins for Google, Facebook, GitHub, X
30
+ - `OAuthManager`: Handle OAuth 2.0 logins for Google, Facebook, GitHub, X and Linkedin
31
31
  ---
32
32
 
33
33
  ## 🚀 Example: Initialize library (CommonJS)
@@ -50,7 +50,7 @@ const auth = new AuthVerify({
50
50
 
51
51
  ```js
52
52
  // create JWT
53
- const token = await auth.jwt.sign({ userId: 123 }, '1h'); // expiry string or number (ms)
53
+ const token = await auth.jwt.sign({ userId: 123 }, '1h'); // expiry string or number (ms) (and also you can add '1m' (minute), '5s' (second) and '7d' (day))
54
54
  console.log('token', token);
55
55
 
56
56
  // verify
@@ -186,6 +186,11 @@ try {
186
186
  }
187
187
 
188
188
  // Callback style also supported: auth.otp.verify({check, code}, callback)
189
+ auth.otp.verify({ check: 'user@example.com', code: '123456' }, (err, isValid)=>{
190
+ if(err) console.log(err);
191
+ if(isValid) console.log('Correct code!');
192
+ else console.log('Incorrect code!');
193
+ });
189
194
  ```
190
195
 
191
196
  ### Resend and cooldown / max attempts
@@ -198,7 +203,7 @@ try {
198
203
 
199
204
  ---
200
205
  ## 🌍 OAuth 2.0 Integration (New in v1.2.0)
201
- `auth.oauth` supports login via Google, Facebook, GitHub, and X (Twitter).
206
+ `auth.oauth` supports login via Google, Facebook, GitHub, X (Twitter) and Linkedin.
202
207
  ### Example (Google Login with Express)
203
208
  ```js
204
209
  const express = require('express');
@@ -272,6 +277,13 @@ const twitter = auth.oauth.x({
272
277
  redirectUri: "http://localhost:3000/auth/x/callback",
273
278
  });
274
279
 
280
+ // --- Example: Linkedin LOGIN ---
281
+ const linkedin = auth.oauth.linkedin({
282
+ clientId: "YOUR_LINKEDIN_CLIENT_ID",
283
+ clientSecret: "YOUR_LINKEDIN_CLIENT_SECRET",
284
+ redirectUri: "http://localhost:3000/auth/linkedin/callback"
285
+ });
286
+
275
287
 
276
288
  // ===== FACEBOOK ROUTES =====
277
289
  app.get("/auth/facebook", (req, res) => facebook.redirect(res));
@@ -313,6 +325,19 @@ app.get("/auth/x/callback", async (req, res) => {
313
325
  res.status(400).json({ error: err.message });
314
326
  }
315
327
  });
328
+
329
+ // ==== LINKEDIN ROUTES ====
330
+ app.get("/auth/linkedin", (req, res) => linkedin.redirect(res));
331
+
332
+ app.get("/auth/linkedin/callback", async (req, res)=>{
333
+ try{
334
+ const { code } = req.query;
335
+ const user = await linkedin.callback(code);
336
+ res.json({ success: true, provider: "x", user });
337
+ }catch(err){
338
+ res.status(400).json({ error: err.message });
339
+ }
340
+ });
316
341
 
317
342
 
318
343
  app.listen(PORT, () => console.log(`🚀 Server running at http://localhost:${PORT}`));
package/src/jwt/index.js CHANGED
@@ -265,6 +265,7 @@ class JWTManager {
265
265
  if (typeof expiry === "number") return expiry;
266
266
  if (typeof expiry !== "string") return 3600000; // default 1h
267
267
  const num = parseInt(expiry);
268
+ if (expiry.endsWith("d")) return num * 3600000 * 24;
268
269
  if (expiry.endsWith("h")) return num * 3600000;
269
270
  if (expiry.endsWith("m")) return num * 60000;
270
271
  if (expiry.endsWith("s")) return num * 1000;
@@ -175,6 +175,66 @@ class OAuthManager {
175
175
  },
176
176
  };
177
177
  }
178
+
179
+ // --- LINKEDIN LOGIN ---
180
+ linkedin({ clientId, clientSecret, redirectUri }) {
181
+ return {
182
+ // Step 1: Redirect user to LinkedIn's authorization page
183
+ redirect(res) {
184
+ const linkedinURL =
185
+ "https://www.linkedin.com/oauth/v2/authorization?" +
186
+ new URLSearchParams({
187
+ response_type: "code",
188
+ client_id: clientId,
189
+ redirect_uri: redirectUri,
190
+ scope: "r_liteprofile r_emailaddress",
191
+ state: "secure123", // optional: you can randomize this
192
+ });
193
+ res.redirect(linkedinURL);
194
+ },
195
+
196
+ // Step 2: Handle callback, exchange code for token, then get user data
197
+ async callback(code) {
198
+ // Exchange authorization code for access token
199
+ const tokenRes = await fetch("https://www.linkedin.com/oauth/v2/accessToken", {
200
+ method: "POST",
201
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
202
+ body: new URLSearchParams({
203
+ grant_type: "authorization_code",
204
+ code,
205
+ redirect_uri: redirectUri,
206
+ client_id: clientId,
207
+ client_secret: clientSecret,
208
+ }),
209
+ });
210
+
211
+ const tokenData = await tokenRes.json();
212
+ if (tokenData.error)
213
+ throw new Error("OAuth Error: " + tokenData.error_description);
214
+
215
+ // Fetch basic profile info
216
+ const profileRes = await fetch("https://api.linkedin.com/v2/me", {
217
+ headers: { Authorization: `Bearer ${tokenData.access_token}` },
218
+ });
219
+ const profile = await profileRes.json();
220
+
221
+ // Fetch user's primary email
222
+ const emailRes = await fetch(
223
+ "https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))",
224
+ { headers: { Authorization: `Bearer ${tokenData.access_token}` } }
225
+ );
226
+ const emailData = await emailRes.json();
227
+
228
+ return {
229
+ id: profile.id,
230
+ name: profile.localizedFirstName + " " + profile.localizedLastName,
231
+ email: emailData.elements?.[0]?.["handle~"]?.emailAddress || null,
232
+ access_token: tokenData.access_token,
233
+ };
234
+ },
235
+ };
236
+ }
237
+
178
238
  }
179
239
 
180
240
  module.exports = OAuthManager;