@dbs-portal/core-api
Version:
HTTP client and API utilities for DBS Portal
310 lines • 11.3 kB
JavaScript
/**
* Authentication mock handlers
*/
import { createHandler } from './factory';
/**
* Generate random string
*/
function generateString(length = 10) {
const charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
let result = '';
for (let i = 0; i < length; i++) {
result += charset.charAt(Math.floor(Math.random() * charset.length));
}
return result;
}
/**
* Generate unique ID
*/
function generateId() {
return `id_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
}
/**
* Mock authentication store
*/
class MockAuthStore {
users = new Map();
sessions = new Map();
tokens = new Map(); // token -> userId
constructor() {
// Add default test user
this.addUser({
id: 'user-1',
email: 'test@example.com',
username: 'testuser',
password: 'password123',
firstName: 'Test',
lastName: 'User',
roles: ['user'],
permissions: ['read', 'write'],
isActive: true,
});
// Add admin user
this.addUser({
id: 'admin-1',
email: 'admin@example.com',
username: 'admin',
password: 'admin123',
firstName: 'Admin',
lastName: 'User',
roles: ['admin', 'user'],
permissions: ['read', 'write', 'delete', 'admin'],
isActive: true,
});
}
addUser(user) {
this.users.set(user.id, user);
}
findUserByCredentials(email, password) {
for (const user of this.users.values()) {
if ((user.email === email || user.username === email) && user.password === password) {
return user;
}
}
return null;
}
findUserById(id) {
return this.users.get(id) || null;
}
findUserByToken(token) {
const userId = this.tokens.get(token);
return userId ? this.findUserById(userId) : null;
}
createSession(user) {
const token = `mock_token_${generateString(32)}`;
const refreshToken = `mock_refresh_${generateString(32)}`;
const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(); // 24 hours
const authContext = {
isAuthenticated: true,
user,
token,
roles: user.roles || [],
permissions: user.permissions || [],
};
this.sessions.set(token, authContext);
this.tokens.set(token, user.id);
return { token, refreshToken, expiresAt };
}
validateToken(token) {
return this.sessions.get(token) || null;
}
revokeToken(token) {
const session = this.sessions.get(token);
if (session) {
this.sessions.delete(token);
this.tokens.delete(token);
return true;
}
return false;
}
refreshToken(_refreshToken) {
// Simple refresh logic - in real implementation, you'd validate the refresh token
// For now, just generate new tokens
const newToken = `mock_token_${generateString(32)}`;
const newRefreshToken = `mock_refresh_${generateString(32)}`;
const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString();
return { token: newToken, refreshToken: newRefreshToken, expiresAt };
}
}
const authStore = new MockAuthStore();
/**
* Create authentication handlers
*/
export function createAuthHandlers(basePath = '/api/auth') {
// POST /auth/login
const loginHandler = createHandler('POST', `${basePath}/login`, {
response: async (request) => {
const { email, password } = request.body;
if (!email || !password) {
return {
success: false,
message: 'Email and password are required',
errors: [
{ code: 'VALIDATION_ERROR', message: 'Email is required', field: 'email' },
{ code: 'VALIDATION_ERROR', message: 'Password is required', field: 'password' },
].filter(error => (error.field === 'email' && !email) ||
(error.field === 'password' && !password)),
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
}
const user = authStore.findUserByCredentials(email, password);
if (!user) {
return {
success: false,
message: 'Invalid credentials',
errors: [{ code: 'INVALID_CREDENTIALS', message: 'Invalid email or password' }],
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
}
if (!user.isActive) {
return {
success: false,
message: 'Account is disabled',
errors: [{ code: 'ACCOUNT_DISABLED', message: 'Your account has been disabled' }],
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
}
const session = authStore.createSession(user);
return {
success: true,
data: {
user: {
id: user.id,
email: user.email,
username: user.username,
firstName: user.firstName,
lastName: user.lastName,
roles: user.roles,
permissions: user.permissions,
},
tokens: {
accessToken: session.token,
refreshToken: session.refreshToken,
expiresAt: session.expiresAt,
tokenType: 'Bearer',
},
},
message: 'Login successful',
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
},
});
// POST /auth/logout
const logoutHandler = createHandler('POST', `${basePath}/logout`, {
response: async (request) => {
const authHeader = request.headers.get('authorization');
const token = authHeader?.replace('Bearer ', '');
if (token) {
authStore.revokeToken(token);
}
return {
success: true,
data: null,
message: 'Logout successful',
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
},
});
// GET /auth/me
const meHandler = createHandler('GET', `${basePath}/me`, {
response: async (request) => {
const authHeader = request.headers.get('authorization');
const token = authHeader?.replace('Bearer ', '');
if (!token) {
return {
success: false,
message: 'Authorization token required',
errors: [{ code: 'UNAUTHORIZED', message: 'Authorization token is required' }],
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
}
const authContext = authStore.validateToken(token);
if (!authContext) {
return {
success: false,
message: 'Invalid or expired token',
errors: [{ code: 'INVALID_TOKEN', message: 'Token is invalid or expired' }],
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
}
return {
success: true,
data: {
id: authContext.user.id,
email: authContext.user.email,
username: authContext.user.username,
firstName: authContext.user.firstName,
lastName: authContext.user.lastName,
roles: authContext.roles,
permissions: authContext.permissions,
},
message: 'User profile retrieved successfully',
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
},
});
// POST /auth/refresh
const refreshHandler = createHandler('POST', `${basePath}/refresh`, {
response: async (request) => {
const { refreshToken } = request.body;
if (!refreshToken) {
return {
success: false,
message: 'Refresh token is required',
errors: [{ code: 'VALIDATION_ERROR', message: 'Refresh token is required' }],
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
}
const newTokens = authStore.refreshToken(refreshToken);
if (!newTokens) {
return {
success: false,
message: 'Invalid refresh token',
errors: [{ code: 'INVALID_REFRESH_TOKEN', message: 'Refresh token is invalid or expired' }],
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
}
return {
success: true,
data: {
accessToken: newTokens.token,
refreshToken: newTokens.refreshToken,
expiresAt: newTokens.expiresAt,
tokenType: 'Bearer',
},
message: 'Token refreshed successfully',
meta: {
timestamp: new Date().toISOString(),
requestId: generateId(),
version: '1.0.0',
},
};
},
});
return [loginHandler, logoutHandler, meHandler, refreshHandler];
}
/**
* Default authentication handlers
*/
export const authHandlers = createAuthHandlers();
//# sourceMappingURL=auth-handlers.js.map