Package Exports
- auth-verify
- auth-verify/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (auth-verify) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
auth-verify
auth-verify is a Node.js authentication utility that provides:
- ✅ Secure OTP (one-time password) generation and verification
- ✅ Sending OTPs via Email, SMS (pluggable helpers), and Telegram bot
- ✅ JWT creation, verification and optional token revocation with memory/Redis storage
- ✅ Session management (in-memory or Redis)
- ✅ New: OAuth 2.0 integration for Google, Facebook, GitHub, and X (Twitter)
- ⚙️ Developer extensibility: custom senders and auth.register.sender() / auth.use(name).send(...)
🧩 Installation
# from npm (when published)
npm install auth-verify
# or locally during development
# copy the package into your project and `require` it`⚙️ Quick overview
AuthVerify(entry): constructs and exposes.jwt,.otp, (optionally).sessionand.oauthmanagers.JWTManager: sign, verify, decode, revoke tokens. SupportsstoreTokens: "memory" | "redis" | "none".OTPManager: generate, store, send, verify, resend OTPs. SupportsstoreTokens: "memory" | "redis" | "none". Supports email, SMS helper, Telegram bot, and custom dev senders.SessionManager: simple session creation/verification/destroy with memory or Redis backend.OAuthManager: Handle OAuth 2.0 logins for Google, Facebook, GitHub, X and Linkedin
🚀 Example: Initialize library (CommonJS)
const AuthVerify = require('auth-verify');
const auth = new AuthVerify({
jwtSecret: "super_secret_value",
storeTokens: "memory", // or "redis" or "none"
otpExpiry: "5m", // supports number (seconds) OR string like '30s', '5m', '1h'
otpHash: "sha256", // optional OTP hashing algorithm
// you may pass redisUrl inside managers' own options when using redis
});🔐 JWT Usage
// create JWT
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))
console.log('token', token);
// verify
const decoded = await auth.jwt.verify(token);
console.log('decoded', decoded);
// decode without verification
const payload = await auth.jwt.decode(token);
// revoke a token (immediately)
await auth.jwt.revoke(token, 0);
// revoke token until a time in the future (e.g. '10m' or number ms)
await auth.jwt.revokeUntil(token, '10m');
// check if token is revoked (returns boolean)
const isRevoked = await auth.jwt.isRevoked(token);🍪 Automatic Cookie Handling (v1.1.0+)
You can now automatically store and verify JWTs via HTTP cookies — no need to manually send them!
const AuthVerify = require("auth-verify");
const express = require("express");
const app = express();
const auth = new AuthVerify({
jwtSecret: "supersecret", storeTokens: "memory"
});
app.post("/login", async (req, res) => {
const token = await auth.jwt.sign({ userId: 1 }, "5s", { res });
res.json({ token }); // token is also set as cookie automatically
});
app.get("/verify", async (req, res) => {
try {
const data = await auth.jwt.verify(req); // auto reads from cookie
res.json({ valid: true, data });
} catch (err) {
res.json({ valid: false, error: err.message });
}
});
app.listen(3000, () => console.log("🚀 Server running at http://localhost:3000"));What it does automatically:
- Saves token in a secure HTTP-only cookie
- Reads and verifies token from cookies
- Supports both async/await and callback styles
Notes:
signandverifysupport callback and promise styles in the implementation. WhenstoreTokensis"redis"you should use the promise/async style (callback mode returns an error for redis in the current implementation).
🔢 OTP (email / sms / telegram / custom sender)
🤝 Configure sender
You can set the default sender (email/sms/telegram):
// email example
auth.otp.setSender({
via: 'email',
sender: 'your@address.com',
pass: 'app-password-or-smtp-pass',
service: 'gmail' // or 'smtp'
// if smtp service: host, port, secure (boolean)
});
// sms example (the internal helper expects provider/apiKey or mock flag)
auth.otp.setSender({
via: 'sms',
provider: 'infobip',
apiKey: 'xxx',
apiSecret: 'yyy',
sender: 'SENDER_NAME',
mock: true // in dev prints message instead of sending
});
// telegram example
auth.otp.setSender({
via: 'telegram',
token: '123:ABC', // bot token
// call auth.otp.setupTelegramBot(token) to start the bot
});⛓️ Generate → Save → Send (chainable)
OTP generation is chainable: generate() returns the OTP manager instance.
// chainable + callback style example
auth.otp.generate(6).set('user@example.com', (err) => {
if (err) throw err;
auth.otp.message({
to: 'user@example.com',
subject: 'Your OTP',
html: `Your code: <b>${auth.otp.code}</b>`
}, (err, info) => {
if (err) console.error('send error', err);
else console.log('sent', info && info.messageId);
});
});Async/await style:
await auth.otp.generate(6); // generates and stores `auth.otp.code`
await auth.otp.set('user@example.com'); // saves OTP into memory/redis
await auth.otp.message({
to: 'user@example.com',
subject: 'Verify',
html: `Your code: <b>${auth.otp.code}</b>`
});✔️ Verify
// Promise style
try {
const ok = await auth.otp.verify({ check: 'user@example.com', code: '123456' });
console.log('verified', ok);
} catch (err) {
console.error('verify failed', err.message);
}
// Callback style also supported: auth.otp.verify({check, code}, callback)
auth.otp.verify({ check: 'user@example.com', code: '123456' }, (err, isValid)=>{
if(err) console.log(err);
if(isValid) console.log('Correct code!');
else console.log('Incorrect code!');
});Resend and cooldown / max attempts
auth.otp.cooldown('30s')orauth.otp.cooldown(30000)— set cooldown duration.auth.otp.maxAttempt(5)— set maximum attempts allowed.auth.otp.resend(identifier)— regenerate and resend OTP, observing cooldown and expiry rules.
resend returns the new code (promise style) or calls callback.
🌍 OAuth 2.0 Integration (New in v1.2.0)
auth.oauth supports login via Google, Facebook, GitHub, X (Twitter) and Linkedin.
Example (Google Login with Express)
const express = require('express');
const AuthVerify = require("auth-verify");
const app = express();
app.use(express.json());
const auth = new AuthVerify({ jwtSecret: 's', storeTokens: 'memory'});
const google = auth.oauth.google({clientId: 'YOUR_CLIENT_ID', clientSecret: 'YOUR_CLIENT_SECRET', redirectUri: 'http://localhost:3000/auth/google/callback'});
app.get('/', async (req, res) => {
res.send(`
<h1>Login with Google</h1>
<a href="/auth/google">Login</a>
`);
});
app.get('/auth/google', (req, res) => google.redirect(res));
app.get('/auth/google/callback', async (req, res)=>{
const code = req.query.code;
try {
const user = await google.callback(code);
res.send(`
<h2>Welcome, ${user.name}!</h2>
<img src="${user.picture}" width="100" style="border-radius:50%">
<p>Email: ${user.email}</p>
<p>Access Token: ${user.access_token.slice(0, 20)}...</p>
`);
} catch(err){
res.status(500).send("Error: " + err.message);
}
});
app.listen(3000, ()=>{
console.log('Server is running...');
});API documentation for OAuth
auth.oauth.google({...})for making connection to your Google cloud app.google.redirect(res)for sending user/client to the Google OAuth page for verifying and selecting his accaountgoogle.callback(code)for exchanging server code to the user/client token.
Other examples with other platforms
const express = require('express');
const AuthVerify = require("auth-verify");
const app = express();
app.use(express.json());
const auth = new AuthVerify({ jwtSecret: 's', storeTokens: 'memory'});
// --- Example: FACEBOOK LOGIN ---
const facebook = auth.oauth.facebook({
clientId: "YOUR_FB_APP_ID",
clientSecret: "YOUR_FB_APP_SECRET",
redirectUri: "http://localhost:3000/auth/facebook/callback",
});
// --- Example: GITHUB LOGIN ---
const github = auth.oauth.github({
clientId: "YOUR_GITHUB_CLIENT_ID",
clientSecret: "YOUR_GITHUB_CLIENT_SECRET",
redirectUri: "http://localhost:3000/auth/github/callback",
});
// --- Example: X (Twitter) LOGIN ---
const twitter = auth.oauth.x({
clientId: "YOUR_TWITTER_CLIENT_ID",
clientSecret: "YOUR_TWITTER_CLIENT_SECRET",
redirectUri: "http://localhost:3000/auth/x/callback",
});
// --- Example: Linkedin LOGIN ---
const linkedin = auth.oauth.linkedin({
clientId: "YOUR_LINKEDIN_CLIENT_ID",
clientSecret: "YOUR_LINKEDIN_CLIENT_SECRET",
redirectUri: "http://localhost:3000/auth/linkedin/callback"
});
// ===== FACEBOOK ROUTES =====
app.get("/auth/facebook", (req, res) => facebook.redirect(res));
app.get("/auth/facebook/callback", async (req, res) => {
try {
const { code } = req.query;
const user = await facebook.callback(code);
res.json({ success: true, provider: "facebook", user });
} catch (err) {
res.status(400).json({ error: err.message });
}
});
// ===== GITHUB ROUTES =====
app.get("/auth/github", (req, res) => github.redirect(res));
app.get("/auth/github/callback", async (req, res) => {
try {
const { code } = req.query;
const user = await github.callback(code);
res.json({ success: true, provider: "github", user });
} catch (err) {
res.status(400).json({ error: err.message });
}
});
// ===== X (TWITTER) ROUTES =====
app.get("/auth/x", (req, res) => twitter.redirect(res));
app.get("/auth/x/callback", async (req, res) => {
try {
const { code } = req.query;
const user = await twitter.callback(code);
res.json({ success: true, provider: "x", user });
} catch (err) {
res.status(400).json({ error: err.message });
}
});
// ==== LINKEDIN ROUTES ====
app.get("/auth/linkedin", (req, res) => linkedin.redirect(res));
app.get("/auth/linkedin/callback", async (req, res)=>{
try{
const { code } = req.query;
const user = await linkedin.callback(code);
res.json({ success: true, provider: "x", user });
}catch(err){
res.status(400).json({ error: err.message });
}
});
app.listen(PORT, () => console.log(`🚀 Server running at http://localhost:${PORT}`));
Telegram integration
There are two ways to use Telegram flow:
Use the built-in
senderConfig.via = 'telegram'and callauth.otp.setupTelegramBot(botToken)— this starts a polling bot that asks users to share their phone via/start, and then matches the phone to in-memory/Redis OTP records and replies with the code.Developer-supplied custom sender (see below) — you can create your own bot and call it from
auth.use(...).send(...)or register viaauth.register.sender().
Important: Only one bot using long polling must be running per bot token — if you get 409 Conflict it's because another process or instance is already polling that bot token.
Developer extensibility (custom senders)
You can register custom senders and use them:
// register a named sender function
auth.register.sender('consoleOtp', async ({ to, code }) => {
console.log(`[DEV SEND] send to ${to}: ${code}`);
});
// use it later (chainable)
await auth.use('consoleOtp').send({ to: '+998901234567', code: await auth.otp.generate(5) });When a custom sender is registered, auth.otp.message() will first attempt the customSender before falling back to built-in providers.
SessionManager
const SessionManager = require('./src/session'); // or auth.session after export
const sessions = new SessionManager({ storeTokens: 'redis' });
// create
const sessionId = await sessions.create('user123', { expiresIn: '2h' });
// verify
const userId = await sessions.verify(sessionId);
// destroy
await sessions.destroy(sessionId);Notes:
expiresInaccepts numeric seconds or strings like'30s','5m','1h','1d'.
Helpers
helpers/helper.js exposes utility functions used by managers:
generateSecureOTP(length, hashAlgorithm)— returns secure numeric OTP stringparseTime(strOrNumber)— converts'1h' | '30s' | numberinto millisecondsresendGeneratedOTP(params)— helper to send email via nodemailer (used by resend)sendSMS(params)— helper for sending SMS using supported providers or mock
Error handling and notes
- Many methods support both callback and Promise (async/await) styles. When using Redis store, prefer async/await (callback variants intentionally return an error when Redis is selected).
- OTP storage keys are the user identifier you pass (email or phone number). Keep identifiers consistent.
- Be careful when using Telegram polling: do not run two instances with polling true for the same bot token (use webhooks or a single process).
- When configuring SMTP (non-Gmail), provide
host,portandsecureinsetSender().
Suggested folder structure
auth-verify/
├─ README.md
├─ package.json
├─ src/
│ ├─ index.js // exports AuthVerify
│ ├─ jwt/
| | ├─ index.js
| | ├─ cookie/index.js
│ ├─ /otp/index.js
│ ├─ /session/index.js
| ├─ /oauth/index.js
│ └─ helpers/helper.jsContributing & License
Contributions welcome! Open issues / PRs for bugs, improvements, or API suggestions.
MIT © 2025 — Jahongir Sobirov