TypeScript-first authentication built on Passport.js. Better DX, same battle-tested reliability.
Cipher Auth wraps Passport.js with a modern TypeScript API and Mongoose integration. Get the reliability of Passport with the developer experience you deserve.
- ๐ฏ Passport.js Foundation - Battle-tested authentication, enhanced with TypeScript
- ๐ Type-Safe - Full TypeScript support throughout
- ๐ฆ Mongoose Integration - Pre-built local strategy with Mongoose
- โก Simple Setup - One class, three methods, done
- ๐จ Flexible - Use our wrapper or drop down to raw Passport
- ๐ Production Ready - Used by thousands via Passport.js
pnpm add @cipher-d-dev/core @cipher-d-dev/cipher-local mongoose bcryptimport express from 'express';
import session from 'express-session';
import { MongooseCipherAuthLocalStrategy } from '@cipher-d-dev/cipher-local';
import cipher_auth from '@cipher-d-dev/core';
import UserModel from './models/User';
const app = express();
// Session middleware
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false
}));
// Initialize Cipher Auth
const authStrategy = new MongooseCipherAuthLocalStrategy(
UserModel,
'email', // unique field (email or username)
'password' // password field
);
authStrategy.initialize();
authStrategy.cipherSerialize();
authStrategy.cipherDeserialize();
// Apply Passport middleware
app.use(cipher_auth.initialize());
app.use(cipher_auth.session());
// Login route
app.post('/login',
cipher_auth.authenticate('local', {
successRedirect: '/dashboard',
failureRedirect: '/login'
})
);
// Logout route
app.post('/logout', (req, res) => {
req.logout(() => {
res.redirect('/');
});
});
// Protected route
app.get('/dashboard', (req, res) => {
if (!req.isAuthenticated()) {
return res.redirect('/login');
}
res.json({ user: req.user });
});
app.listen(3000);Passport.js TypeScript wrapper with enhanced type safety.
import cipher_auth from '@cipher-d-dev/core';
// cipher_auth is Passport with TypeScript types
cipher_auth.use(strategy);
cipher_auth.authenticate('local');Local authentication strategy with Mongoose integration.
Pre-built Strategy:
import { MongooseCipherAuthLocalStrategy } from '@cipher-d-dev/cipher-local';
const authStrategy = new MongooseCipherAuthLocalStrategy(
UserModel,
'email', // or 'username'
'password'
);
authStrategy.initialize();
authStrategy.cipherSerialize();
authStrategy.cipherDeserialize();Custom Strategy:
import { CipherLocal } from '@cipher-d-dev/cipher-local';
import cipher_auth from '@cipher-d-dev/core';
cipher_auth.use(
new CipherLocal(
{
usernameField: 'email',
passwordField: 'password'
},
async (email, password, done) => {
// Your custom logic
const user = await findUserByEmail(email);
const valid = await verifyPassword(password, user.passwordHash);
if (valid) {
done(null, user);
} else {
done(null, false, { message: 'Invalid credentials' });
}
}
)
);import { Schema, model } from 'mongoose';
import bcrypt from 'bcrypt';
const UserSchema = new Schema({
email: {
type: String,
required: true,
unique: true,
lowercase: true
},
password: {
type: String,
required: true
},
name: String,
createdAt: {
type: Date,
default: Date.now
}
});
// Hash password before saving
UserSchema.pre('save', async function(next) {
if (!this.isModified('password')) return next();
this.password = await bcrypt.hash(this.password, 10);
next();
});
export default model('User', UserSchema);new MongooseCipherAuthLocalStrategy(
userModel: Model<any>, // Mongoose model
uniqueField?: string, // 'email' | 'username' (default: 'username')
passwordField?: string // default: 'password'
)Methods:
initialize()- Configures the local strategycipherSerialize()- Sets up user serializationcipherDeserialize()- Sets up user deserialization
new CipherLocal(
options: {
usernameField: string;
passwordField: string;
},
verify: (username, password, done) => void
)1. User submits login form
โ
2. Express receives POST /login
โ
3. cipher_auth.authenticate('local') triggers
โ
4. CipherLocal strategy executes:
- Finds user by email/username
- Compares password with bcrypt
โ
5. On success:
- User serialized to session (user.id)
- Redirect to dashboard
โ
6. Subsequent requests:
- User deserialized from session
- Available as req.user
import bcrypt from 'bcrypt';
// Hash password (in pre-save hook)
const hash = await bcrypt.hash(password, 10);
// Verify password (in strategy)
const valid = await bcrypt.compare(password, user.password);app.use(session({
secret: process.env.SESSION_SECRET, // Strong secret!
resave: false,
saveUninitialized: false,
cookie: {
secure: process.env.NODE_ENV === 'production', // HTTPS only in prod
httpOnly: true, // Prevent XSS
maxAge: 24 * 60 * 60 * 1000 // 24 hours
}
}));// Middleware
function requireAuth(req, res, next) {
if (!req.isAuthenticated()) {
return res.status(401).json({ error: 'Not authenticated' });
}
next();
}
// Usage
app.get('/api/profile', requireAuth, (req, res) => {
res.json({ user: req.user });
});<form action="/login" method="POST">
<input type="email" name="email" required />
<input type="password" name="password" required />
<button type="submit">Login</button>
</form>async function login(email: string, password: string) {
const response = await fetch('/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include', // Important for cookies!
body: JSON.stringify({ email, password })
});
if (response.ok) {
window.location.href = '/dashboard';
} else {
const error = await response.json();
console.error(error);
}
}- TypeScript wrapper for Passport.js
- Local strategy with Mongoose
- Full type safety
- Session management
- React components & hooks (
@cipher-d-dev/react) - OAuth strategies (Google, GitHub, Facebook)
- Magic link authentication
- Two-factor authentication (TOTP)
- Prisma adapter
- Next.js integration helpers
- Pre-built UI components
- WebAuthn/Passkeys
- SAML 2.0 for enterprise SSO
- Vue & Svelte components
- CLI for scaffolding
- Admin dashboard
- โ Battle-tested (10+ years in production)
- โ 500+ authentication strategies
- โ Trusted by millions of applications
- โ Active maintenance and security updates
- โ TypeScript-first - Passport's types aren't great
- โ Mongoose integration - No boilerplate needed
- โ Modern patterns - Async/await over callbacks
- โ Better DX - Simpler setup, clearer APIs
- โ Extensible - Drop down to Passport when needed
// Use our wrapper
const auth = new MongooseCipherAuthLocalStrategy(UserModel);
// Or use Passport directly
cipher_auth.use(new PassportGoogleStrategy({...}));Built on top of:
- Passport.js - The authentication foundation
- Mongoose - MongoDB object modeling
- bcrypt - Password hashing
MIT ยฉ cipher-d-dev
- ๐ Documentation
- ๐ Issue Tracker
- ๐ฌ Discord Community
- ๐ฆ Twitter
Built with โค๏ธ for developers who deserve better auth DX
Get Started โข View Examples โข Star on GitHub