const {
JWTManager,
APIKeyManager,
EdgeSessionManager,
OAuthClient
} = require('edge-utils/auth');
// Initialize managers
const jwt = new JWTManager({
secret: process.env.JWT_SECRET,
issuer: 'my-app',
audience: 'users'
});
const apiKeys = new APIKeyManager({
hmacSecret: process.env.API_KEY_SECRET,
storage: kvStorage
});
const sessions = new EdgeSessionManager({
secret: process.env.SESSION_SECRET,
storage: kvStorage
});
const oauth = new OAuthClient({
provider: 'google',
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
redirectUri: `${process.env.APP_URL}/oauth/callback`
});
// Authentication endpoints
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
// Login with credentials
if (url.pathname === '/auth/login' && request.method === 'POST') {
const { email, password } = await request.json();
// Validate credentials (implement your own logic)
const user = await validateCredentials(email, password);
if (!user) {
return new Response('Invalid credentials', { status: 401 });
}
// Create session
const sessionId = await sessions.create({
userId: user.id,
email: user.email,
role: user.role
}, user.id);
// Generate tokens
const accessToken = jwt.generate({
userId: user.id,
email: user.email,
role: user.role
});
const refreshToken = jwt.generate({
userId: user.id,
type: 'refresh'
}, { expiresIn: '7d' });
const response = new Response(JSON.stringify({
accessToken,
refreshToken,
sessionId
}), {
headers: { 'Content-Type': 'application/json' }
});
// Set session cookie
await sessions.setCookie(response, sessionId);
return response;
}
// OAuth login
if (url.pathname === '/auth/oauth/login') {
const authUrl = oauth.getAuthorizationUrl({
state: generateState(),
scope: ['openid', 'profile', 'email']
});
return new Response(null, {
status: 302,
headers: { Location: authUrl }
});
}
// OAuth callback
if (url.pathname === '/auth/oauth/callback') {
const { code, state } = Object.fromEntries(url.searchParams);
// Verify state
if (!verifyState(state)) {
return new Response('Invalid state', { status: 400 });
}
// Exchange code for tokens
const tokens = await oauth.exchangeCode(code);
// Get user info from ID token
const userInfo = jwt.decode(tokens.idToken);
// Create session and tokens
const sessionId = await sessions.create({
userId: userInfo.sub,
email: userInfo.email,
name: userInfo.name
}, userInfo.sub);
const accessToken = jwt.generate({
userId: userInfo.sub,
email: userInfo.email,
name: userInfo.name
});
const response = new Response(null, {
status: 302,
headers: { Location: '/dashboard' }
});
await sessions.setCookie(response, sessionId);
return response;
}
// Refresh token
if (url.pathname === '/auth/refresh' && request.method === 'POST') {
const { refreshToken } = await request.json();
const newTokens = await jwt.refresh(refreshToken);
if (!newTokens) {
return new Response('Invalid refresh token', { status: 401 });
}
return new Response(JSON.stringify(newTokens), {
headers: { 'Content-Type': 'application/json' }
});
}
// Logout
if (url.pathname === '/auth/logout' && request.method === 'POST') {
const sessionData = await sessions.getFromRequest(request);
if (sessionData) {
await sessions.destroy(sessionData.id);
}
const response = new Response('Logged out');
await sessions.clearCookie(response);
return response;
}
// API key generation
if (url.pathname === '/auth/api-keys' && request.method === 'POST') {
const sessionData = await sessions.getFromRequest(request);
if (!sessionData) {
return new Response('Authentication required', { status: 401 });
}
const { name, permissions } = await request.json();
const apiKey = apiKeys.generate({
name,
permissions,
metadata: { createdBy: sessionData.userId }
});
return new Response(JSON.stringify(apiKey), {
headers: { 'Content-Type': 'application/json' }
});
}
return new Response('Not found', { status: 404 });
}
};