mbkauthe
Version:
MBKTech's reusable authentication system for Node.js applications.
342 lines (296 loc) • 8.78 kB
TypeScript
// Type definitions for mbkauthe
// Project: https://github.com/MIbnEKhalid/mbkauthe
// Definitions by: Muhammad Bin Khalid <https://github.com/MIbnEKhalid>
import { Request, Response, NextFunction, Router } from 'express';
import { Pool } from 'pg';
// Global augmentations must be at the top level, outside any declare module blocks
declare global {
namespace Express {
interface Request {
user?: {
username: string;
role: 'SuperAdmin' | 'NormalUser' | 'Guest';
fullname?: string;
};
userRole?: 'SuperAdmin' | 'NormalUser' | 'Guest';
}
interface Session {
user?: {
id: number;
username: string;
fullname?: string;
role: 'SuperAdmin' | 'NormalUser' | 'Guest';
sessionId?: string;
allowedApps?: string[];
tokenScope?: 'read-only' | 'write' | null;
};
preAuthUser?: {
id: number;
username: string;
role: 'SuperAdmin' | 'NormalUser' | 'Guest';
loginMethod?: 'password' | 'github' | 'google';
redirectUrl?: string | null;
allowedApps?: string[];
};
oauthRedirect?: string;
oauthCsrfToken?: string;
[key: string]: any;
}
}
}
declare module 'mbkauthe' {
// Configuration Types
export interface MBKAuthConfig {
APP_NAME: string;
SESSION_SECRET_KEY: string;
Main_SECRET_TOKEN: string;
IS_DEPLOYED: 'true' | 'false' | 'f';
DOMAIN: string;
LOGIN_DB: string;
MBKAUTH_TWO_FA_ENABLE: 'true' | 'false' | 'f';
COOKIE_EXPIRE_TIME?: number;
DEVICE_TRUST_DURATION_DAYS?: number;
GITHUB_LOGIN_ENABLED?: 'true' | 'false' | 'f';
GITHUB_APP_SLUG?: string;
GITHUB_APP_CLIENT_ID?: string;
GITHUB_APP_CLIENT_SECRET?: string;
GOOGLE_LOGIN_ENABLED?: 'true' | 'false' | 'f';
GOOGLE_CLIENT_ID?: string;
GOOGLE_CLIENT_SECRET?: string;
loginRedirectURL?: string;
MAX_SESSIONS_PER_USER?: number;
}
export interface OAuthConfig {
GITHUB_LOGIN_ENABLED?: 'true' | 'false' | 'f';
GITHUB_APP_SLUG?: string;
GITHUB_APP_CLIENT_ID?: string;
GITHUB_APP_CLIENT_SECRET?: string;
GOOGLE_LOGIN_ENABLED?: 'true' | 'false' | 'f';
GOOGLE_CLIENT_ID?: string;
GOOGLE_CLIENT_SECRET?: string;
}
// User Types
export type UserRole = 'SuperAdmin' | 'NormalUser' | 'Guest';
export interface SessionUser {
id: number;
username: string;
fullname?: string;
role: UserRole;
sessionId?: string;
allowedApps?: string[];
}
export interface PreAuthUser {
id: number;
username: string;
role: UserRole;
allowedApps?: string[];
loginMethod?: 'password' | 'github' | 'google';
redirectUrl?: string | null;
}
// Database Types
export interface DBUser {
id: number;
UserName: string;
PasswordEnc?: string;
Role: UserRole;
Active: boolean;
AllowedApps: string[];
created_at?: Date;
updated_at?: Date;
last_login?: Date;
}
export interface TwoFARecord {
UserName: string;
TwoFAStatus: boolean;
TwoFASecret?: string;
}
export interface TrustedDevice {
id: number;
UserName: string;
DeviceToken: string;
DeviceName?: string;
UserAgent?: string;
IpAddress?: string;
CreatedAt: Date;
ExpiresAt: Date;
LastUsed: Date;
}
export interface GitHubUser {
id: number;
user_name: string;
github_id: string;
github_username: string;
installation_id?: number;
installation_target_type?: string;
access_token: string;
created_at: Date;
updated_at: Date;
}
export interface GoogleUser {
id: number;
user_name: string;
google_id: string;
google_email: string;
access_token: string;
created_at: Date;
updated_at: Date;
}
// API Token Types
export type TokenScope = 'read-only' | 'write';
export interface TokenPermissions {
scope: TokenScope;
allowedApps: string[] | null;
}
export interface ApiToken {
id: number;
UserName: string;
Name: string;
TokenHash: string;
Prefix: string;
Permissions: TokenPermissions;
LastUsed?: Date;
CreatedAt: Date;
ExpiresAt?: Date;
}
// API Response Types
export interface LoginResponse {
success: boolean;
message: string;
sessionId?: string;
twoFactorRequired?: boolean;
redirectUrl?: string;
errorCode?: number;
}
export interface LogoutResponse {
success: boolean;
message: string;
}
export interface TwoFAVerifyResponse {
success: boolean;
message: string;
sessionId?: string;
redirectUrl?: string;
}
export interface ErrorResponse {
success: false;
message: string;
errorCode?: number;
}
// Error Render Options
export interface ErrorRenderOptions {
layout?: boolean;
code: number | string;
error: string;
message: string;
page?: string;
pagename?: string;
details?: string;
app?: string;
version?: string;
}
// Middleware Types
export type AuthMiddleware = (
req: Request,
res: Response,
next: NextFunction
) => void | Promise<void>;
// Middleware Functions
export function validateSession(
req: Request,
res: Response,
next: NextFunction
): void | Promise<void>;
export function validateApiSession(
req: Request,
res: Response,
next: NextFunction
): void | Promise<void>;
export function checkRolePermission(
requiredRole: UserRole | 'Any' | 'any',
notAllowed?: UserRole
): AuthMiddleware;
export function validateSessionAndRole(
requiredRole: UserRole | 'Any' | 'any',
notAllowed?: UserRole
): AuthMiddleware;
export const sessVal: AuthMiddleware;
export const sessRole: AuthMiddleware;
export const strictValidateSession: AuthMiddleware;
export function strictValidateSessionAndRole(
requiredRole: UserRole | 'Any' | 'any',
notAllowed?: UserRole
): AuthMiddleware;
export function authenticate(token: string): AuthMiddleware;
// Reload session user values from DB and refresh cookies.
// Returns true when session is refreshed and valid, false if session invalidated.
export function reloadSessionUser(req: Request, res: Response): Promise<boolean>;
// Utility Functions
// Renders an error page — signature is (res, req, options)
export function renderError(
res: Response,
req: Request,
options: ErrorRenderOptions
): Response;
// Return a lightweight context object used to populate templates
export function getUserContext(req: Request): {
userLoggedIn: boolean;
isuserlogin: boolean;
username: string;
fullname: string;
role: string;
allowedApps: string[];
};
// Renders a template page with optional layout and data
export function renderPage(
req: Request,
res: Response,
fileLocation: string,
layout?: boolean,
data?: Record<string, any>
): Promise<Response>;
// Error utilities
export const ErrorCodes: { [key: string]: number };
export const ErrorMessages: { [key: number]: { message: string; userMessage?: string; hint?: string } };
export function getErrorByCode(errorCode: number, customData?: any): { errorCode: number; message: string; userMessage?: string; hint?: string } & any;
export function createErrorResponse(statusCode: number, errorCode: number, customData?: any): any;
export function logError(context: string, errorCode: number, additionalInfo?: any): void;
export function getCookieOptions(): {
maxAge: number;
domain?: string;
secure: boolean;
sameSite: 'lax';
path: string;
httpOnly: boolean;
};
export function getClearCookieOptions(): {
domain?: string;
secure: boolean;
sameSite: 'lax';
path: string;
httpOnly: boolean;
};
export function generateDeviceToken(): string;
export function getDeviceTokenCookieOptions(): {
maxAge: number;
domain?: string;
secure: boolean;
sameSite: 'lax';
path: string;
httpOnly: boolean;
};
export function hashPassword(password: string, username: string): string;
export function clearSessionCookies(res: Response): void;
export function getLatestVersion(): Promise<string>;
// Exports
export const dblogin: Pool;
export const mbkautheVar: MBKAuthConfig;
export const cachedCookieOptions: ReturnType<typeof getCookieOptions>;
export const cachedClearCookieOptions: ReturnType<typeof getClearCookieOptions>;
export const packageJson: { version: string; [key: string]: any };
export const appVersion: string;
export const DEVICE_TRUST_DURATION_DAYS: number;
export const DEVICE_TRUST_DURATION_MS: number;
// Default Export (Express Router)
const router: Router;
export default router;
}