@astralibx/staff-engine 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -0
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -70,6 +70,20 @@ app.listen(3000);
|
|
|
70
70
|
### Permissions
|
|
71
71
|
|
|
72
72
|
- **Runtime-configurable groups via API** -- `POST /permission-groups` creates a named group with permission entries. Groups have `groupId`, `label`, `sortOrder`, and an array of entries (key, label, type). No redeploy required to define new permissions.
|
|
73
|
+
|
|
74
|
+
> **Note:** Permission groups use `label` for display text and `groupId` for the unique identifier -- not `name`.
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
await engine.permissions.createGroup({
|
|
78
|
+
groupId: 'chat-management', // unique identifier, kebab-case
|
|
79
|
+
label: 'Chat Management', // display text shown in UI
|
|
80
|
+
permissions: [
|
|
81
|
+
{ key: 'chat:view', label: 'View chats', type: 'view' },
|
|
82
|
+
{ key: 'chat:edit', label: 'Edit chats', type: 'edit' },
|
|
83
|
+
],
|
|
84
|
+
sortOrder: 1,
|
|
85
|
+
});
|
|
86
|
+
```
|
|
73
87
|
- **Edit-to-view cascade** -- when granting a permission ending in `.edit`, the corresponding `.view` key is automatically required. The engine validates this on `PUT /:id/permissions`.
|
|
74
88
|
- **Permission cache (Redis or in-memory)** -- each staff member's resolved permission list is cached after the first lookup. TTL is `permissionCacheTtlMs` (default 5 min). Cache is invalidated immediately on `updatePermissions` or `updateStatus`.
|
|
75
89
|
- **Owner bypasses all checks** -- `requirePermission` middleware skips the permission check entirely when `req.user.role === 'owner'`.
|
|
@@ -122,6 +136,27 @@ The factory function returns a single `StaffEngine` object:
|
|
|
122
136
|
| `engine.models` | Mongoose models (`Staff`, `PermissionGroup`) |
|
|
123
137
|
| `engine.destroy()` | Flush permission cache and clean up resources |
|
|
124
138
|
|
|
139
|
+
## Seeding Data
|
|
140
|
+
|
|
141
|
+
Schema factory functions are exported so you can seed data or run scripts without creating a full engine instance:
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
import { createStaffModel, createPermissionGroupModel } from '@astralibx/staff-engine';
|
|
145
|
+
|
|
146
|
+
const Staff = createStaffModel(connection);
|
|
147
|
+
const PermissionGroup = createPermissionGroupModel(connection);
|
|
148
|
+
|
|
149
|
+
await PermissionGroup.create({
|
|
150
|
+
groupId: 'admin',
|
|
151
|
+
label: 'Admin',
|
|
152
|
+
permissions: [
|
|
153
|
+
{ key: 'chat:view', label: 'View chats', type: 'view' },
|
|
154
|
+
{ key: 'chat:edit', label: 'Edit chats', type: 'edit' },
|
|
155
|
+
],
|
|
156
|
+
sortOrder: 1,
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
125
160
|
## Redis Key Prefix (Required for Multi-Project Deployments)
|
|
126
161
|
|
|
127
162
|
> **WARNING:** If multiple projects share the same Redis server, you MUST set a unique `keyPrefix` per project. Without this, rate limiter state and permission cache entries will collide across projects.
|
package/dist/index.cjs
CHANGED
|
@@ -698,11 +698,11 @@ function createAuthMiddleware(jwtSecret, permissionCache, StaffModel, logger, te
|
|
|
698
698
|
if (!payload.staffId || !payload.role) return null;
|
|
699
699
|
const filter = { _id: payload.staffId };
|
|
700
700
|
if (tenantId) filter.tenantId = tenantId;
|
|
701
|
-
const staff = await StaffModel.findOne(filter).select("status role").lean();
|
|
701
|
+
const staff = await StaffModel.findOne(filter).select("name email status role").lean();
|
|
702
702
|
if (!staff) return null;
|
|
703
703
|
if (staff.status !== staffTypes.STAFF_STATUS.Active) return null;
|
|
704
704
|
const permissions = await permissionCache.get(payload.staffId);
|
|
705
|
-
return { staffId: payload.staffId, role: staff.role, permissions };
|
|
705
|
+
return { staffId: payload.staffId, name: staff.name, email: staff.email, role: staff.role, permissions };
|
|
706
706
|
} catch {
|
|
707
707
|
return null;
|
|
708
708
|
}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/schemas/staff.schema.ts","../src/schemas/permission-group.schema.ts","../src/services/rate-limiter.service.ts","../src/services/permission-cache.service.ts","../src/constants/index.ts","../src/errors/index.ts","../src/services/permission.service.ts","../src/validation/permissions.ts","../src/validation/config.schema.ts","../src/services/staff.service.ts","../src/services/auth.service.ts","../src/middleware/auth.middleware.ts","../src/utils/error-handler.ts","../src/routes/auth.routes.ts","../src/routes/staff.routes.ts","../src/routes/permission-group.routes.ts","../src/routes/index.ts","../src/index.ts"],"names":["Schema","STAFF_ROLE_VALUES","STAFF_STATUS_VALUES","STAFF_STATUS","PERMISSION_TYPE_VALUES","AlxError","PERMISSION_TYPE","z","STAFF_ROLE","jwt","sendError","Router","sendSuccess","DEFAULT_OPTIONS","noopLogger"],"mappings":"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","file":"index.cjs","sourcesContent":["import { Schema, type Connection, type Model, type Document, type Types } from 'mongoose';\nimport { STAFF_ROLE_VALUES, STAFF_STATUS_VALUES, STAFF_STATUS } from '@astralibx/staff-types';\nimport type { IStaff } from '@astralibx/staff-types';\n\nexport interface IStaffDocument extends Omit<IStaff, '_id'>, Document {\n _id: Types.ObjectId;\n}\n\nexport function createStaffModel(connection: Connection, prefix?: string): Model<IStaffDocument> {\n const schema = new Schema<IStaffDocument>(\n {\n name: { type: String, required: true, trim: true },\n email: { type: String, required: true, trim: true, lowercase: true },\n password: { type: String, required: true, select: false },\n role: { type: String, enum: STAFF_ROLE_VALUES, default: 'staff' },\n status: { type: String, enum: STAFF_STATUS_VALUES, default: STAFF_STATUS.Pending },\n permissions: { type: [String], default: [] },\n externalUserId: { type: String, sparse: true },\n lastLoginAt: { type: Date },\n lastLoginIp: { type: String },\n metadata: { type: Schema.Types.Mixed },\n tenantId: { type: String, sparse: true },\n },\n { timestamps: true },\n );\n\n schema.index({ email: 1, tenantId: 1 }, { unique: true });\n schema.index({ status: 1 });\n schema.index({ role: 1 });\n\n const collectionName = prefix ? `${prefix}_staff` : 'staff';\n return connection.model<IStaffDocument>('Staff', schema, collectionName);\n}\n","import { Schema, type Connection, type Model, type Document, type Types } from 'mongoose';\nimport { PERMISSION_TYPE_VALUES } from '@astralibx/staff-types';\nimport type { IPermissionGroup } from '@astralibx/staff-types';\n\nexport interface IPermissionGroupDocument extends Omit<IPermissionGroup, '_id'>, Document {\n _id: Types.ObjectId;\n}\n\nconst permissionEntrySchema = new Schema(\n {\n key: { type: String, required: true },\n label: { type: String, required: true },\n type: { type: String, enum: PERMISSION_TYPE_VALUES, required: true },\n },\n { _id: false },\n);\n\nexport function createPermissionGroupModel(\n connection: Connection,\n prefix?: string,\n): Model<IPermissionGroupDocument> {\n const schema = new Schema<IPermissionGroupDocument>(\n {\n groupId: { type: String, required: true },\n label: { type: String, required: true, trim: true },\n permissions: { type: [permissionEntrySchema], default: [] },\n sortOrder: { type: Number, default: 0 },\n tenantId: { type: String, index: true, sparse: true },\n },\n { timestamps: true },\n );\n\n schema.index({ groupId: 1, tenantId: 1 }, { unique: true });\n schema.index({ sortOrder: 1 });\n\n const collectionName = prefix ? `${prefix}_permission_groups` : 'permission_groups';\n return connection.model<IPermissionGroupDocument>('PermissionGroup', schema, collectionName);\n}\n","import type { LogAdapter } from '@astralibx/staff-types';\n\ninterface RateLimitEntry {\n count: number;\n expiresAt: number;\n}\n\nexport class RateLimiterService {\n private memoryStore = new Map<string, RateLimitEntry>();\n\n constructor(\n private windowMs: number,\n private maxAttempts: number,\n private redis: unknown | null,\n private keyPrefix: string,\n private logger: LogAdapter,\n ) {}\n\n async checkLimit(key: string): Promise<{ allowed: boolean; remaining: number; retryAfterMs?: number }> {\n if (this.redis) {\n return this.checkLimitRedis(key);\n }\n return this.checkLimitMemory(key);\n }\n\n async recordAttempt(key: string): Promise<void> {\n if (this.redis) {\n return this.recordAttemptRedis(key);\n }\n this.recordAttemptMemory(key);\n }\n\n async reset(key: string): Promise<void> {\n if (this.redis) {\n await (this.redis as any).del(`${this.keyPrefix}rate:${key}`);\n return;\n }\n this.memoryStore.delete(key);\n }\n\n private checkLimitMemory(key: string): { allowed: boolean; remaining: number; retryAfterMs?: number } {\n const entry = this.memoryStore.get(key);\n if (!entry || Date.now() > entry.expiresAt) {\n return { allowed: true, remaining: this.maxAttempts };\n }\n if (entry.count >= this.maxAttempts) {\n return { allowed: false, remaining: 0, retryAfterMs: entry.expiresAt - Date.now() };\n }\n return { allowed: true, remaining: this.maxAttempts - entry.count };\n }\n\n private recordAttemptMemory(key: string): void {\n const entry = this.memoryStore.get(key);\n if (!entry || Date.now() > entry.expiresAt) {\n this.memoryStore.set(key, { count: 1, expiresAt: Date.now() + this.windowMs });\n } else {\n entry.count++;\n }\n }\n\n private async checkLimitRedis(key: string): Promise<{ allowed: boolean; remaining: number; retryAfterMs?: number }> {\n const redisKey = `${this.keyPrefix}rate:${key}`;\n const redis = this.redis as any;\n const count = await redis.get(redisKey);\n const current = count ? parseInt(count, 10) : 0;\n if (current >= this.maxAttempts) {\n const ttl = await redis.pttl(redisKey);\n return { allowed: false, remaining: 0, retryAfterMs: ttl > 0 ? ttl : this.windowMs };\n }\n return { allowed: true, remaining: this.maxAttempts - current };\n }\n\n private async recordAttemptRedis(key: string): Promise<void> {\n const redisKey = `${this.keyPrefix}rate:${key}`;\n const redis = this.redis as any;\n const count = await redis.incr(redisKey);\n if (count === 1) {\n await redis.pexpire(redisKey, this.windowMs);\n }\n }\n}\n","import type { Model } from 'mongoose';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport type { IStaffDocument } from '../schemas/staff.schema.js';\n\nexport class PermissionCacheService {\n private memoryCache = new Map<string, { permissions: string[]; expiresAt: number }>();\n\n constructor(\n private StaffModel: Model<IStaffDocument>,\n private ttlMs: number,\n private redis: unknown | null,\n private keyPrefix: string,\n private logger: LogAdapter,\n private tenantId?: string,\n ) {}\n\n async get(staffId: string): Promise<string[]> {\n if (this.redis) {\n return this.getRedis(staffId);\n }\n return this.getMemory(staffId);\n }\n\n async invalidate(staffId: string): Promise<void> {\n if (this.redis) {\n await (this.redis as any).del(`${this.keyPrefix}perms:${staffId}`);\n return;\n }\n this.memoryCache.delete(staffId);\n }\n\n async invalidateAll(): Promise<void> {\n if (this.redis) {\n const redis = this.redis as any;\n const keys = await redis.keys(`${this.keyPrefix}perms:*`);\n if (keys.length > 0) {\n await redis.del(...keys);\n }\n return;\n }\n this.memoryCache.clear();\n }\n\n private async getMemory(staffId: string): Promise<string[]> {\n const cached = this.memoryCache.get(staffId);\n if (cached && Date.now() < cached.expiresAt) {\n return cached.permissions;\n }\n const permissions = await this.fetchFromDb(staffId);\n this.memoryCache.set(staffId, { permissions, expiresAt: Date.now() + this.ttlMs });\n return permissions;\n }\n\n private async getRedis(staffId: string): Promise<string[]> {\n const redisKey = `${this.keyPrefix}perms:${staffId}`;\n const redis = this.redis as any;\n const cached = await redis.get(redisKey);\n if (cached) {\n return JSON.parse(cached);\n }\n const permissions = await this.fetchFromDb(staffId);\n await redis.set(redisKey, JSON.stringify(permissions), 'PX', this.ttlMs);\n return permissions;\n }\n\n private async fetchFromDb(staffId: string): Promise<string[]> {\n const filter: Record<string, unknown> = { _id: staffId };\n if (this.tenantId) filter.tenantId = this.tenantId;\n const staff = await this.StaffModel.findOne(filter).select('permissions').lean();\n return staff?.permissions ?? [];\n }\n}\n","export const ERROR_CODE = {\n // Auth\n InvalidCredentials: 'STAFF_INVALID_CREDENTIALS',\n AccountInactive: 'STAFF_ACCOUNT_INACTIVE',\n AccountPending: 'STAFF_ACCOUNT_PENDING',\n RateLimited: 'STAFF_RATE_LIMITED',\n TokenExpired: 'STAFF_TOKEN_EXPIRED',\n TokenInvalid: 'STAFF_TOKEN_INVALID',\n InsufficientPermissions: 'STAFF_INSUFFICIENT_PERMISSIONS',\n OwnerOnly: 'STAFF_OWNER_ONLY',\n\n // CRUD\n StaffNotFound: 'STAFF_NOT_FOUND',\n EmailExists: 'STAFF_EMAIL_EXISTS',\n SetupAlreadyComplete: 'STAFF_SETUP_ALREADY_COMPLETE',\n LastOwnerGuard: 'STAFF_LAST_OWNER_GUARD',\n InvalidPermissions: 'STAFF_INVALID_PERMISSIONS',\n\n // Permission Groups\n GroupNotFound: 'STAFF_GROUP_NOT_FOUND',\n GroupIdExists: 'STAFF_GROUP_ID_EXISTS',\n\n // Config\n InvalidConfig: 'STAFF_INVALID_CONFIG',\n} as const;\n\nexport type ErrorCode = (typeof ERROR_CODE)[keyof typeof ERROR_CODE];\n\nexport const ERROR_MESSAGE = {\n InvalidCredentials: 'Invalid email or password',\n AccountInactive: 'Account is deactivated',\n AccountPending: 'Account is pending activation',\n RateLimited: 'Too many login attempts. Please try again later.',\n TokenExpired: 'Token has expired',\n TokenInvalid: 'Invalid token',\n InsufficientPermissions: 'Insufficient permissions',\n OwnerOnly: 'This action requires owner privileges',\n StaffNotFound: 'Staff member not found',\n EmailExists: 'A staff member with this email already exists',\n SetupAlreadyComplete: 'Initial setup has already been completed',\n LastOwnerGuard: 'Cannot deactivate the last active owner',\n InvalidPermissions: 'Edit permissions require corresponding view permissions',\n GroupNotFound: 'Permission group not found',\n GroupIdExists: 'A permission group with this ID already exists',\n InvalidConfig: 'Invalid engine configuration',\n} as const;\n\nexport const DEFAULTS = {\n ListPageSize: 20,\n MaxListPageSize: 100,\n PermissionCacheTtlMs: 5 * 60 * 1000,\n} as const;\n\nexport const DEFAULT_AUTH = {\n staffTokenExpiry: '24h',\n ownerTokenExpiry: '30d',\n permissionCacheTtlMs: 5 * 60 * 1000,\n} as const;\n","import { AlxError } from '@astralibx/core';\nimport { ERROR_CODE, ERROR_MESSAGE } from '../constants/index.js';\n\nexport class AlxStaffError extends AlxError {\n constructor(\n message: string,\n code: string,\n public readonly context?: Record<string, unknown>,\n ) {\n super(message, code);\n this.name = 'AlxStaffError';\n }\n}\n\nexport class AuthenticationError extends AlxStaffError {\n constructor(code: string = ERROR_CODE.InvalidCredentials, message?: string) {\n super(message || ERROR_MESSAGE.InvalidCredentials, code);\n this.name = 'AuthenticationError';\n }\n}\n\nexport class AuthorizationError extends AlxStaffError {\n constructor(code: string = ERROR_CODE.InsufficientPermissions, message?: string) {\n super(message || ERROR_MESSAGE.InsufficientPermissions, code);\n this.name = 'AuthorizationError';\n }\n}\n\nexport class RateLimitError extends AlxStaffError {\n constructor(public readonly retryAfterMs: number) {\n super(ERROR_MESSAGE.RateLimited, ERROR_CODE.RateLimited, { retryAfterMs });\n this.name = 'RateLimitError';\n }\n}\n\nexport class TokenError extends AlxStaffError {\n constructor(code: string = ERROR_CODE.TokenInvalid, message?: string) {\n super(message || ERROR_MESSAGE.TokenInvalid, code);\n this.name = 'TokenError';\n }\n}\n\nexport class StaffNotFoundError extends AlxStaffError {\n constructor(public readonly staffId: string) {\n super(ERROR_MESSAGE.StaffNotFound, ERROR_CODE.StaffNotFound, { staffId });\n this.name = 'StaffNotFoundError';\n }\n}\n\nexport class DuplicateError extends AlxStaffError {\n constructor(code: string, message: string, context?: Record<string, unknown>) {\n super(message, code, context);\n this.name = 'DuplicateError';\n }\n}\n\nexport class SetupError extends AlxStaffError {\n constructor() {\n super(ERROR_MESSAGE.SetupAlreadyComplete, ERROR_CODE.SetupAlreadyComplete);\n this.name = 'SetupError';\n }\n}\n\nexport class LastOwnerError extends AlxStaffError {\n constructor(public readonly staffId: string) {\n super(ERROR_MESSAGE.LastOwnerGuard, ERROR_CODE.LastOwnerGuard, { staffId });\n this.name = 'LastOwnerError';\n }\n}\n\nexport class InvalidPermissionError extends AlxStaffError {\n constructor(public readonly missingViewKeys: string[]) {\n super(ERROR_MESSAGE.InvalidPermissions, ERROR_CODE.InvalidPermissions, { missingViewKeys });\n this.name = 'InvalidPermissionError';\n }\n}\n\nexport class GroupNotFoundError extends AlxStaffError {\n constructor(public readonly groupId: string) {\n super(ERROR_MESSAGE.GroupNotFound, ERROR_CODE.GroupNotFound, { groupId });\n this.name = 'GroupNotFoundError';\n }\n}\n\nexport class InvalidConfigError extends AlxStaffError {\n constructor(public readonly field: string, public readonly reason: string) {\n super(`Invalid config for \"${field}\": ${reason}`, ERROR_CODE.InvalidConfig, { field, reason });\n this.name = 'InvalidConfigError';\n }\n}\n","import type { Model } from 'mongoose';\nimport type { LogAdapter, IPermissionGroupCreateInput, IPermissionGroupUpdateInput } from '@astralibx/staff-types';\nimport type { IPermissionGroupDocument } from '../schemas/permission-group.schema.js';\nimport { DuplicateError, GroupNotFoundError } from '../errors/index.js';\nimport { ERROR_CODE, ERROR_MESSAGE } from '../constants/index.js';\nimport type { PermissionCacheService } from './permission-cache.service.js';\n\nexport class PermissionService {\n constructor(\n private PermissionGroup: Model<IPermissionGroupDocument>,\n private permissionCache: PermissionCacheService,\n private logger: LogAdapter,\n private tenantId?: string,\n ) {}\n\n private get tenantFilter(): Record<string, unknown> {\n return this.tenantId ? { tenantId: this.tenantId } : {};\n }\n\n async listGroups(): Promise<IPermissionGroupDocument[]> {\n return this.PermissionGroup.find(this.tenantFilter).sort({ sortOrder: 1 }).lean() as unknown as IPermissionGroupDocument[];\n }\n\n async createGroup(data: IPermissionGroupCreateInput): Promise<IPermissionGroupDocument> {\n const existing = await this.PermissionGroup.findOne({\n groupId: data.groupId,\n ...this.tenantFilter,\n });\n if (existing) {\n throw new DuplicateError(\n ERROR_CODE.GroupIdExists,\n ERROR_MESSAGE.GroupIdExists,\n { groupId: data.groupId },\n );\n }\n const group = await this.PermissionGroup.create({\n ...data,\n sortOrder: data.sortOrder ?? 0,\n ...this.tenantFilter,\n });\n this.logger.info('Permission group created', { groupId: data.groupId });\n return group.toObject();\n }\n\n async updateGroup(groupId: string, data: IPermissionGroupUpdateInput): Promise<IPermissionGroupDocument> {\n const group = await this.PermissionGroup.findOneAndUpdate(\n { groupId, ...this.tenantFilter },\n { $set: data },\n { new: true },\n ).lean();\n if (!group) {\n throw new GroupNotFoundError(groupId);\n }\n await this.permissionCache.invalidateAll();\n this.logger.info('Permission group updated', { groupId, fields: Object.keys(data) });\n return group as unknown as IPermissionGroupDocument;\n }\n\n async deleteGroup(groupId: string): Promise<void> {\n const result = await this.PermissionGroup.deleteOne({ groupId, ...this.tenantFilter });\n if (result.deletedCount === 0) {\n throw new GroupNotFoundError(groupId);\n }\n await this.permissionCache.invalidateAll();\n this.logger.info('Permission group deleted', { groupId });\n }\n\n async getAllPermissionKeys(): Promise<string[]> {\n const groups = await this.listGroups();\n return groups.flatMap(g => g.permissions.map(p => p.key));\n }\n}\n","import { PERMISSION_TYPE } from '@astralibx/staff-types';\nimport { InvalidPermissionError } from '../errors/index.js';\nimport type { IPermissionGroupDocument } from '../schemas/permission-group.schema.js';\n\n/**\n * Validates that for every edit-type permission, the corresponding view-type permission\n * is also present. Single-level cascade only.\n * Example: 'chat:edit' requires 'chat:view'\n */\nexport function validatePermissionPairs(\n permissions: string[],\n allGroups: IPermissionGroupDocument[],\n): void {\n const allEntries = allGroups.flatMap(g => g.permissions);\n const editKeys = allEntries\n .filter(e => e.type === PERMISSION_TYPE.Edit)\n .map(e => e.key);\n\n const permissionSet = new Set(permissions);\n const missingViewKeys: string[] = [];\n\n for (const editKey of editKeys) {\n if (!permissionSet.has(editKey)) continue;\n const prefix = editKey.substring(0, editKey.lastIndexOf(':'));\n const viewKey = `${prefix}:view`;\n const viewEntry = allEntries.find(e => e.key === viewKey && e.type === PERMISSION_TYPE.View);\n if (viewEntry && !permissionSet.has(viewKey)) {\n missingViewKeys.push(viewKey);\n }\n }\n\n if (missingViewKeys.length > 0) {\n throw new InvalidPermissionError(missingViewKeys);\n }\n}\n","import { z } from 'zod';\n\nexport const StaffEngineConfigSchema = z.object({\n db: z.object({\n connection: z.unknown().refine((v) => v !== undefined && v !== null, {\n message: 'db.connection is required',\n }),\n collectionPrefix: z.string().optional(),\n }),\n redis: z\n .object({\n connection: z.unknown(),\n keyPrefix: z.string().optional(),\n })\n .optional(),\n logger: z\n .object({\n info: z.function(),\n warn: z.function(),\n error: z.function(),\n })\n .optional(),\n tenantId: z.string().optional(),\n auth: z.object({\n jwtSecret: z.string().min(1),\n staffTokenExpiry: z.string().optional(),\n ownerTokenExpiry: z.string().optional(),\n permissionCacheTtlMs: z.number().int().positive().optional(),\n }),\n adapters: z.object({\n hashPassword: z.function(),\n comparePassword: z.function(),\n }),\n hooks: z\n .object({\n onStaffCreated: z.function().optional(),\n onLogin: z.function().optional(),\n onLoginFailed: z.function().optional(),\n onPermissionsChanged: z.function().optional(),\n onStatusChanged: z.function().optional(),\n onMetric: z.function().optional(),\n })\n .optional(),\n options: z\n .object({\n requireEmailUniqueness: z.boolean().optional(),\n allowSelfPasswordChange: z.boolean().optional(),\n rateLimiter: z\n .object({\n windowMs: z.number().int().positive().optional(),\n maxAttempts: z.number().int().positive().optional(),\n })\n .optional(),\n })\n .optional(),\n});\n","import type { Model } from 'mongoose';\nimport type {\n LogAdapter, StaffHooks, StaffAdapters, IStaffCreateInput,\n IStaffUpdateInput, IStaffListFilters, IPaginatedResult,\n} from '@astralibx/staff-types';\nimport { STAFF_ROLE, STAFF_STATUS } from '@astralibx/staff-types';\nimport type { IStaffDocument } from '../schemas/staff.schema.js';\nimport type { IPermissionGroupDocument } from '../schemas/permission-group.schema.js';\nimport type { PermissionCacheService } from './permission-cache.service.js';\nimport {\n DuplicateError, StaffNotFoundError,\n LastOwnerError,\n} from '../errors/index.js';\nimport { ERROR_CODE, ERROR_MESSAGE, DEFAULTS } from '../constants/index.js';\nimport { validatePermissionPairs } from '../validation/index.js';\n\nexport interface StaffServiceDeps {\n Staff: Model<IStaffDocument>;\n PermissionGroup: Model<IPermissionGroupDocument>;\n adapters: StaffAdapters;\n hooks: StaffHooks;\n permissionCache: PermissionCacheService;\n logger: LogAdapter;\n tenantId?: string;\n requireEmailUniqueness: boolean;\n}\n\nexport class StaffService {\n private Staff: Model<IStaffDocument>;\n private PermissionGroup: Model<IPermissionGroupDocument>;\n private adapters: StaffAdapters;\n private hooks: StaffHooks;\n private permissionCache: PermissionCacheService;\n private logger: LogAdapter;\n private tenantId?: string;\n private requireEmailUniqueness: boolean;\n\n constructor(deps: StaffServiceDeps) {\n this.Staff = deps.Staff;\n this.PermissionGroup = deps.PermissionGroup;\n this.adapters = deps.adapters;\n this.hooks = deps.hooks;\n this.permissionCache = deps.permissionCache;\n this.logger = deps.logger;\n this.tenantId = deps.tenantId;\n this.requireEmailUniqueness = deps.requireEmailUniqueness;\n }\n\n private get tenantFilter(): Record<string, unknown> {\n return this.tenantId ? { tenantId: this.tenantId } : {};\n }\n\n async create(data: IStaffCreateInput): Promise<IStaffDocument> {\n if (this.requireEmailUniqueness) {\n const existing = await this.Staff.findOne({\n email: data.email.toLowerCase().trim(),\n ...this.tenantFilter,\n });\n if (existing) {\n throw new DuplicateError(ERROR_CODE.EmailExists, ERROR_MESSAGE.EmailExists, { email: data.email });\n }\n }\n\n const hashedPassword = await this.adapters.hashPassword(data.password);\n const staff = await this.Staff.create({\n ...data,\n email: data.email.toLowerCase().trim(),\n password: hashedPassword,\n role: data.role ?? STAFF_ROLE.Staff,\n status: data.status ?? STAFF_STATUS.Pending,\n permissions: data.permissions ?? [],\n ...this.tenantFilter,\n });\n\n this.logger.info('Staff created', { staffId: staff._id.toString() });\n this.hooks.onStaffCreated?.(staff.toObject());\n return staff.toObject();\n }\n\n async list(filters: IStaffListFilters = {}): Promise<IPaginatedResult<IStaffDocument>> {\n const page = Math.max(1, filters.page ?? 1);\n const limit = Math.min(filters.limit ?? DEFAULTS.ListPageSize, DEFAULTS.MaxListPageSize);\n\n const query: Record<string, unknown> = { ...this.tenantFilter };\n if (filters.status) query.status = filters.status;\n if (filters.role) query.role = filters.role;\n\n const [data, total] = await Promise.all([\n this.Staff.find(query)\n .sort({ createdAt: -1 })\n .skip((page - 1) * limit)\n .limit(limit)\n .lean(),\n this.Staff.countDocuments(query),\n ]);\n\n return {\n data: data as unknown as IStaffDocument[],\n pagination: { page, limit, total, totalPages: Math.ceil(total / limit) },\n };\n }\n\n async getById(staffId: string): Promise<IStaffDocument> {\n const staff = await this.Staff.findOne({ _id: staffId, ...this.tenantFilter }).lean() as unknown as IStaffDocument | null;\n if (!staff) throw new StaffNotFoundError(staffId);\n return staff;\n }\n\n async update(staffId: string, data: IStaffUpdateInput): Promise<IStaffDocument> {\n const updateData: Record<string, unknown> = {};\n if (data.name !== undefined) updateData.name = data.name;\n if (data.email !== undefined) updateData.email = data.email.toLowerCase().trim();\n if (data.metadata !== undefined) updateData.metadata = data.metadata;\n\n if (data.email && this.requireEmailUniqueness) {\n const existing = await this.Staff.findOne({\n email: data.email.toLowerCase().trim(),\n _id: { $ne: staffId },\n ...this.tenantFilter,\n });\n if (existing) {\n throw new DuplicateError(ERROR_CODE.EmailExists, ERROR_MESSAGE.EmailExists, { email: data.email });\n }\n }\n\n const staff = await this.Staff.findOneAndUpdate(\n { _id: staffId, ...this.tenantFilter },\n { $set: updateData },\n { new: true },\n ).lean() as unknown as IStaffDocument | null;\n if (!staff) throw new StaffNotFoundError(staffId);\n\n this.logger.info('Staff updated', { staffId, fields: Object.keys(updateData) });\n return staff;\n }\n\n async updatePermissions(staffId: string, permissions: string[]): Promise<IStaffDocument> {\n const groups = await this.PermissionGroup.find(this.tenantFilter).lean() as unknown as IPermissionGroupDocument[];\n validatePermissionPairs(permissions, groups);\n\n const staff = await this.Staff.findOne({ _id: staffId, ...this.tenantFilter });\n if (!staff) throw new StaffNotFoundError(staffId);\n\n const oldPerms = [...staff.permissions];\n staff.permissions = permissions;\n await staff.save();\n\n await this.permissionCache.invalidate(staffId);\n this.hooks.onPermissionsChanged?.(staffId, oldPerms, permissions);\n this.logger.info('Staff permissions updated', { staffId, count: permissions.length });\n return staff.toObject();\n }\n\n async updateStatus(staffId: string, status: string): Promise<IStaffDocument> {\n const staff = await this.Staff.findOne({ _id: staffId, ...this.tenantFilter });\n if (!staff) throw new StaffNotFoundError(staffId);\n\n if (status === STAFF_STATUS.Inactive && staff.role === STAFF_ROLE.Owner) {\n const activeOwnerCount = await this.Staff.countDocuments({\n role: STAFF_ROLE.Owner,\n status: STAFF_STATUS.Active,\n ...this.tenantFilter,\n });\n if (activeOwnerCount <= 1) throw new LastOwnerError(staffId);\n }\n\n const oldStatus = staff.status;\n staff.status = status as any;\n await staff.save();\n\n await this.permissionCache.invalidate(staffId);\n this.hooks.onStatusChanged?.(staffId, oldStatus, status);\n this.logger.info('Staff status updated', { staffId, oldStatus, newStatus: status });\n return staff.toObject();\n }\n}\n","import jwt from 'jsonwebtoken';\nimport type { Model } from 'mongoose';\nimport type {\n LogAdapter, StaffHooks, StaffAdapters,\n} from '@astralibx/staff-types';\nimport { STAFF_ROLE, STAFF_STATUS } from '@astralibx/staff-types';\nimport type { IStaffDocument } from '../schemas/staff.schema.js';\nimport type { RateLimiterService } from './rate-limiter.service.js';\nimport {\n AuthenticationError, StaffNotFoundError,\n SetupError, RateLimitError,\n} from '../errors/index.js';\nimport { ERROR_CODE, ERROR_MESSAGE } from '../constants/index.js';\n\nexport interface AuthServiceDeps {\n Staff: Model<IStaffDocument>;\n adapters: StaffAdapters;\n hooks: StaffHooks;\n rateLimiter: RateLimiterService;\n logger: LogAdapter;\n tenantId?: string;\n jwtSecret: string;\n staffTokenExpiry: string;\n ownerTokenExpiry: string;\n allowSelfPasswordChange: boolean;\n}\n\nexport class AuthService {\n private Staff: Model<IStaffDocument>;\n private adapters: StaffAdapters;\n private hooks: StaffHooks;\n private rateLimiter: RateLimiterService;\n private logger: LogAdapter;\n private tenantId?: string;\n private jwtSecret: string;\n private staffTokenExpiry: string;\n private ownerTokenExpiry: string;\n private allowSelfPasswordChange: boolean;\n\n constructor(deps: AuthServiceDeps) {\n this.Staff = deps.Staff;\n this.adapters = deps.adapters;\n this.hooks = deps.hooks;\n this.rateLimiter = deps.rateLimiter;\n this.logger = deps.logger;\n this.tenantId = deps.tenantId;\n this.jwtSecret = deps.jwtSecret;\n this.staffTokenExpiry = deps.staffTokenExpiry;\n this.ownerTokenExpiry = deps.ownerTokenExpiry;\n this.allowSelfPasswordChange = deps.allowSelfPasswordChange;\n }\n\n private get tenantFilter(): Record<string, unknown> {\n return this.tenantId ? { tenantId: this.tenantId } : {};\n }\n\n private generateToken(staffId: string, role: string): string {\n const expiresIn = role === STAFF_ROLE.Owner ? this.ownerTokenExpiry : this.staffTokenExpiry;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return jwt.sign({ staffId, role }, this.jwtSecret, { expiresIn } as any);\n }\n\n async setupOwner(data: { name: string; email: string; password: string }): Promise<{ staff: IStaffDocument; token: string }> {\n // Race-safe: check count first, then create. If two requests race past the\n // count check, the unique index on {email, tenantId} will reject the second\n // create, which we catch and convert to SetupError.\n const count = await this.Staff.countDocuments(this.tenantFilter);\n if (count > 0) throw new SetupError();\n\n const hashedPassword = await this.adapters.hashPassword(data.password);\n let staff: IStaffDocument;\n try {\n const doc = await this.Staff.create({\n name: data.name,\n email: data.email.toLowerCase().trim(),\n password: hashedPassword,\n role: STAFF_ROLE.Owner,\n status: STAFF_STATUS.Active,\n permissions: [],\n ...this.tenantFilter,\n });\n staff = doc.toObject() as unknown as IStaffDocument;\n } catch (err: unknown) {\n // Race condition: another request created a staff member between our count and create\n if (err && typeof err === 'object' && 'code' in err && (err as any).code === 11000) {\n throw new SetupError();\n }\n throw err;\n }\n const token = this.generateToken(staff._id.toString(), STAFF_ROLE.Owner);\n this.logger.info('Owner setup complete', { staffId: staff._id.toString() });\n this.hooks.onStaffCreated?.(staff);\n this.hooks.onMetric?.({ name: 'staff_setup_complete', value: 1 });\n return { staff, token };\n }\n\n async login(email: string, password: string, ip?: string): Promise<{ staff: IStaffDocument; token: string }> {\n if (ip) {\n const limit = await this.rateLimiter.checkLimit(ip);\n if (!limit.allowed) {\n this.hooks.onLoginFailed?.(email, ip);\n throw new RateLimitError(limit.retryAfterMs!);\n }\n }\n\n const staff = await this.Staff.findOne({\n email: email.toLowerCase().trim(),\n ...this.tenantFilter,\n }).select('+password');\n\n if (!staff) {\n if (ip) await this.rateLimiter.recordAttempt(ip);\n this.hooks.onLoginFailed?.(email, ip);\n throw new AuthenticationError(ERROR_CODE.InvalidCredentials);\n }\n\n const valid = await this.adapters.comparePassword(password, staff.password);\n if (!valid) {\n if (ip) await this.rateLimiter.recordAttempt(ip);\n this.hooks.onLoginFailed?.(email, ip);\n throw new AuthenticationError(ERROR_CODE.InvalidCredentials);\n }\n\n if (staff.status === STAFF_STATUS.Inactive) {\n throw new AuthenticationError(ERROR_CODE.AccountInactive, ERROR_MESSAGE.AccountInactive);\n }\n if (staff.status === STAFF_STATUS.Pending) {\n throw new AuthenticationError(ERROR_CODE.AccountPending, ERROR_MESSAGE.AccountPending);\n }\n\n staff.lastLoginAt = new Date();\n if (ip) staff.lastLoginIp = ip;\n await staff.save();\n\n if (ip) await this.rateLimiter.reset(ip);\n const token = this.generateToken(staff._id.toString(), staff.role);\n this.hooks.onLogin?.(staff.toObject(), ip);\n this.hooks.onMetric?.({ name: 'staff_login', value: 1, labels: { role: staff.role } });\n this.logger.info('Staff login', { staffId: staff._id.toString() });\n\n const staffObj = staff.toObject();\n delete (staffObj as any).password;\n return { staff: staffObj, token };\n }\n\n async resetPassword(staffId: string, newPassword: string): Promise<void> {\n const staff = await this.Staff.findOne({ _id: staffId, ...this.tenantFilter });\n if (!staff) throw new StaffNotFoundError(staffId);\n\n staff.password = await this.adapters.hashPassword(newPassword);\n await staff.save();\n this.logger.info('Staff password reset', { staffId });\n }\n\n async changeOwnPassword(staffId: string, oldPassword: string, newPassword: string): Promise<void> {\n if (!this.allowSelfPasswordChange) {\n throw new AuthenticationError(ERROR_CODE.InsufficientPermissions, 'Self password change is disabled');\n }\n\n const staff = await this.Staff.findOne({ _id: staffId, ...this.tenantFilter }).select('+password');\n if (!staff) throw new StaffNotFoundError(staffId);\n\n const valid = await this.adapters.comparePassword(oldPassword, staff.password);\n if (!valid) throw new AuthenticationError(ERROR_CODE.InvalidCredentials, 'Current password is incorrect');\n\n staff.password = await this.adapters.hashPassword(newPassword);\n await staff.save();\n this.logger.info('Staff changed own password', { staffId });\n }\n}\n","import jwt from 'jsonwebtoken';\nimport type { Request, Response, NextFunction, RequestHandler } from 'express';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport { STAFF_ROLE, STAFF_STATUS } from '@astralibx/staff-types';\nimport type { PermissionCacheService } from '../services/permission-cache.service.js';\nimport type { IStaffDocument } from '../schemas/staff.schema.js';\nimport type { Model } from 'mongoose';\nimport { TokenError, AuthorizationError } from '../errors/index.js';\nimport { ERROR_CODE, ERROR_MESSAGE } from '../constants/index.js';\n\nexport interface StaffUser {\n staffId: string;\n role: string;\n permissions: string[];\n}\n\nexport interface AuthenticatedRequest extends Request {\n user: StaffUser;\n}\n\nexport interface AuthMiddleware {\n verifyToken: RequestHandler;\n resolveStaff: (token: string) => Promise<StaffUser | null>;\n requirePermission: (...keys: string[]) => RequestHandler;\n ownerOnly: RequestHandler;\n requireRole: (...roles: string[]) => RequestHandler;\n}\n\nexport function createAuthMiddleware(\n jwtSecret: string,\n permissionCache: PermissionCacheService,\n StaffModel: Model<IStaffDocument>,\n logger: LogAdapter,\n tenantId?: string,\n): AuthMiddleware {\n\n async function resolveStaffFromToken(token: string): Promise<StaffUser | null> {\n try {\n const payload = jwt.verify(token, jwtSecret) as { staffId: string; role: string };\n if (!payload.staffId || !payload.role) return null;\n\n // Check staff status\n const filter: Record<string, unknown> = { _id: payload.staffId };\n if (tenantId) filter.tenantId = tenantId;\n const staff = await StaffModel.findOne(filter).select('status role').lean();\n if (!staff) return null;\n if (staff.status !== STAFF_STATUS.Active) return null;\n\n const permissions = await permissionCache.get(payload.staffId);\n return { staffId: payload.staffId, role: staff.role, permissions };\n } catch {\n return null;\n }\n }\n\n const verifyToken: RequestHandler = async (req: Request, res: Response, next: NextFunction) => {\n const authHeader = req.headers.authorization;\n if (!authHeader?.startsWith('Bearer ')) {\n res.status(401).json({ success: false, error: ERROR_MESSAGE.TokenInvalid, code: ERROR_CODE.TokenInvalid });\n return;\n }\n\n const token = authHeader.slice(7);\n\n // Distinguish expired vs invalid tokens before full resolution\n try {\n jwt.verify(token, jwtSecret);\n } catch (err: unknown) {\n if (err instanceof jwt.TokenExpiredError) {\n res.status(401).json({ success: false, error: ERROR_MESSAGE.TokenExpired, code: ERROR_CODE.TokenExpired });\n return;\n }\n res.status(401).json({ success: false, error: ERROR_MESSAGE.TokenInvalid, code: ERROR_CODE.TokenInvalid });\n return;\n }\n\n const user = await resolveStaffFromToken(token);\n if (!user) {\n res.status(401).json({ success: false, error: ERROR_MESSAGE.TokenInvalid, code: ERROR_CODE.TokenInvalid });\n return;\n }\n\n (req as AuthenticatedRequest).user = user;\n next();\n };\n\n function requirePermission(...keys: string[]): RequestHandler {\n return (req: Request, res: Response, next: NextFunction) => {\n const user = (req as AuthenticatedRequest).user;\n if (!user) {\n res.status(401).json({ success: false, error: ERROR_MESSAGE.TokenInvalid, code: ERROR_CODE.TokenInvalid });\n return;\n }\n\n // Owner bypasses permission checks\n if (user.role === STAFF_ROLE.Owner) {\n next();\n return;\n }\n\n const permSet = new Set(user.permissions);\n const missing: string[] = [];\n\n for (const key of keys) {\n if (!permSet.has(key)) {\n missing.push(key);\n continue;\n }\n // Single-level edit→view cascade\n if (key.endsWith(':edit')) {\n const prefix = key.substring(0, key.lastIndexOf(':'));\n const viewKey = `${prefix}:view`;\n if (!permSet.has(viewKey)) {\n missing.push(viewKey);\n }\n }\n }\n\n if (missing.length > 0) {\n res.status(403).json({\n success: false,\n error: ERROR_MESSAGE.InsufficientPermissions,\n code: ERROR_CODE.InsufficientPermissions,\n missing,\n });\n return;\n }\n\n next();\n };\n }\n\n const ownerOnly: RequestHandler = (req: Request, res: Response, next: NextFunction) => {\n const user = (req as AuthenticatedRequest).user;\n if (!user || user.role !== STAFF_ROLE.Owner) {\n res.status(403).json({ success: false, error: ERROR_MESSAGE.OwnerOnly, code: ERROR_CODE.OwnerOnly });\n return;\n }\n next();\n };\n\n function requireRole(...roles: string[]): RequestHandler {\n return (req: Request, res: Response, next: NextFunction) => {\n const user = (req as AuthenticatedRequest).user;\n if (!user || !roles.includes(user.role)) {\n res.status(403).json({ success: false, error: ERROR_MESSAGE.InsufficientPermissions, code: ERROR_CODE.InsufficientPermissions });\n return;\n }\n next();\n };\n }\n\n return {\n verifyToken,\n resolveStaff: resolveStaffFromToken,\n requirePermission,\n ownerOnly,\n requireRole,\n };\n}\n","import type { Response } from 'express';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport { sendSuccess, sendError } from '@astralibx/core';\nimport {\n AlxStaffError, AuthenticationError, AuthorizationError,\n RateLimitError, TokenError, StaffNotFoundError, DuplicateError,\n SetupError, LastOwnerError, InvalidPermissionError, GroupNotFoundError,\n} from '../errors/index.js';\n\nexport { sendSuccess };\n\nfunction sendStaffError(res: Response, error: AlxStaffError, status: number): void {\n res.status(status).json({ success: false, error: error.message, code: error.code });\n}\n\nexport function handleStaffError(res: Response, error: unknown, logger: LogAdapter): void {\n if (error instanceof RateLimitError) {\n res.set('Retry-After', String(Math.ceil(error.retryAfterMs / 1000)));\n sendStaffError(res, error, 429);\n } else if (error instanceof AuthenticationError || error instanceof TokenError) {\n sendStaffError(res, error, 401);\n } else if (error instanceof AuthorizationError || error instanceof SetupError) {\n sendStaffError(res, error, 403);\n } else if (error instanceof StaffNotFoundError || error instanceof GroupNotFoundError) {\n sendStaffError(res, error, 404);\n } else if (error instanceof DuplicateError) {\n sendStaffError(res, error, 409);\n } else if (error instanceof LastOwnerError || error instanceof InvalidPermissionError) {\n sendStaffError(res, error, 400);\n } else if (error instanceof AlxStaffError) {\n sendStaffError(res, error, 400);\n } else {\n const message = error instanceof Error ? error.message : 'Unknown error';\n logger.error('Unexpected error', { error: message });\n sendError(res, message, 500);\n }\n}\n","import { Router } from 'express';\nimport type { Request, Response } from 'express';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport type { StaffService } from '../services/staff.service.js';\nimport type { AuthService } from '../services/auth.service.js';\nimport type { AuthMiddleware, AuthenticatedRequest } from '../middleware/auth.middleware.js';\nimport { sendSuccess, handleStaffError } from '../utils/error-handler.js';\n\nexport function createAuthRoutes(\n staffService: StaffService,\n authService: AuthService,\n auth: AuthMiddleware,\n logger: LogAdapter,\n allowSelfPasswordChange: boolean,\n): Router {\n const router = Router();\n\n // POST /setup — public, creates initial owner account\n router.post('/setup', async (req: Request, res: Response) => {\n try {\n const result = await authService.setupOwner(req.body);\n sendSuccess(res, result, 201);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // POST /login — public, returns staff + token\n router.post('/login', async (req: Request, res: Response) => {\n try {\n const { email, password } = req.body as { email: string; password: string };\n const ip = req.ip || req.socket.remoteAddress || '';\n const result = await authService.login(email, password, ip);\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // GET /me — authenticated, returns current staff profile + permissions\n router.get('/me', auth.verifyToken, async (req: Request, res: Response) => {\n try {\n const user = (req as AuthenticatedRequest).user;\n const staff = await staffService.getById(user.staffId);\n sendSuccess(res, { staff, permissions: user.permissions });\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /me/password — only mounted if allowSelfPasswordChange is true\n if (allowSelfPasswordChange) {\n router.put('/me/password', auth.verifyToken, async (req: Request, res: Response) => {\n try {\n const user = (req as AuthenticatedRequest).user;\n const { oldPassword, newPassword } = req.body as { oldPassword: string; newPassword: string };\n await authService.changeOwnPassword(user.staffId, oldPassword, newPassword);\n sendSuccess(res, { message: 'Password changed successfully' });\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n }\n\n return router;\n}\n","import { Router } from 'express';\nimport type { Request, Response } from 'express';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport type { StaffService } from '../services/staff.service.js';\nimport type { AuthService } from '../services/auth.service.js';\nimport { sendSuccess, handleStaffError } from '../utils/error-handler.js';\n\nexport function createStaffRoutes(\n staffService: StaffService,\n logger: LogAdapter,\n authService?: AuthService,\n): Router {\n const router = Router();\n\n // GET / — list staff\n router.get('/', async (req: Request, res: Response) => {\n try {\n const query = req.query as Record<string, string | undefined>;\n const filters: Record<string, unknown> = {};\n if (query['status']) filters['status'] = query['status'];\n if (query['role']) filters['role'] = query['role'];\n if (query['page']) filters['page'] = parseInt(query['page']!, 10);\n if (query['limit']) filters['limit'] = parseInt(query['limit']!, 10);\n const result = await staffService.list(filters as Parameters<typeof staffService.list>[0]);\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // POST / — create staff member\n router.post('/', async (req: Request, res: Response) => {\n try {\n const result = await staffService.create(req.body);\n sendSuccess(res, result, 201);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /:staffId — update staff member\n router.put('/:staffId', async (req: Request, res: Response) => {\n try {\n const result = await staffService.update(req.params['staffId']!, req.body);\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /:staffId/permissions — update staff permissions\n router.put('/:staffId/permissions', async (req: Request, res: Response) => {\n try {\n const result = await staffService.updatePermissions(\n req.params['staffId']!,\n req.body.permissions,\n );\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /:staffId/status — update staff status\n router.put('/:staffId/status', async (req: Request, res: Response) => {\n try {\n const result = await staffService.updateStatus(\n req.params['staffId']!,\n req.body.status,\n );\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /:staffId/password — reset staff password (owner action)\n router.put('/:staffId/password', async (req: Request, res: Response) => {\n try {\n if (!authService) {\n throw new Error('AuthService not available');\n }\n await authService.resetPassword(req.params['staffId']!, req.body.password);\n sendSuccess(res, { message: 'Password reset successfully' });\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n return router;\n}\n","import { Router } from 'express';\nimport type { Request, Response } from 'express';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport type { PermissionService } from '../services/permission.service.js';\nimport type { AuthMiddleware } from '../middleware/auth.middleware.js';\nimport { sendSuccess, handleStaffError } from '../utils/error-handler.js';\n\nexport function createPermissionGroupRoutes(\n permissionService: PermissionService,\n auth: AuthMiddleware,\n logger: LogAdapter,\n): Router {\n const router = Router();\n\n // GET / — authenticated, list all permission groups\n router.get('/', auth.verifyToken, async (req: Request, res: Response) => {\n try {\n const result = await permissionService.listGroups();\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // POST / — owner only, create permission group\n router.post('/', auth.verifyToken, auth.ownerOnly, async (req: Request, res: Response) => {\n try {\n const result = await permissionService.createGroup(req.body);\n sendSuccess(res, result, 201);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /:groupId — owner only, update permission group\n router.put('/:groupId', auth.verifyToken, auth.ownerOnly, async (req: Request, res: Response) => {\n try {\n const result = await permissionService.updateGroup(req.params['groupId']!, req.body);\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // DELETE /:groupId — owner only, delete permission group\n router.delete('/:groupId', auth.verifyToken, auth.ownerOnly, async (req: Request, res: Response) => {\n try {\n await permissionService.deleteGroup(req.params['groupId']!);\n sendSuccess(res, { message: 'Group deleted successfully' });\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n return router;\n}\n","import { Router } from 'express';\nimport type { StaffService } from '../services/staff.service.js';\nimport type { AuthService } from '../services/auth.service.js';\nimport type { PermissionService } from '../services/permission.service.js';\nimport type { AuthMiddleware } from '../middleware/auth.middleware.js';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport { createAuthRoutes } from './auth.routes.js';\nimport { createStaffRoutes } from './staff.routes.js';\nimport { createPermissionGroupRoutes } from './permission-group.routes.js';\n\nexport interface RouteServices {\n staff: StaffService;\n auth: AuthService;\n permissions: PermissionService;\n}\n\nexport function createRoutes(\n services: RouteServices,\n auth: AuthMiddleware,\n logger: LogAdapter,\n allowSelfPasswordChange: boolean,\n): Router {\n const router = Router();\n\n // Public + authenticated routes (setup, login, /me)\n router.use('/', createAuthRoutes(services.staff, services.auth, auth, logger, allowSelfPasswordChange));\n\n // Owner-only staff CRUD routes\n router.use('/', auth.verifyToken, auth.ownerOnly, createStaffRoutes(services.staff, logger, services.auth));\n\n // Permission group routes (GET is authenticated, CUD is owner-only)\n router.use('/permission-groups', createPermissionGroupRoutes(services.permissions, auth, logger));\n\n return router;\n}\n","import { noopLogger } from '@astralibx/core';\nimport type { Router } from 'express';\nimport type { Model } from 'mongoose';\nimport type { StaffEngineConfig, ResolvedOptions } from '@astralibx/staff-types';\nimport { DEFAULT_OPTIONS } from '@astralibx/staff-types';\nimport { createStaffModel, type IStaffDocument } from './schemas/staff.schema.js';\nimport { createPermissionGroupModel, type IPermissionGroupDocument } from './schemas/permission-group.schema.js';\nimport { RateLimiterService } from './services/rate-limiter.service.js';\nimport { PermissionCacheService } from './services/permission-cache.service.js';\nimport { PermissionService } from './services/permission.service.js';\nimport { StaffService } from './services/staff.service.js';\nimport { AuthService } from './services/auth.service.js';\nimport { createAuthMiddleware, type AuthMiddleware } from './middleware/auth.middleware.js';\nimport { createRoutes } from './routes/index.js';\nimport { DEFAULT_AUTH } from './constants/index.js';\nimport { InvalidConfigError } from './errors/index.js';\nimport { StaffEngineConfigSchema } from './validation/config.schema.js';\n\n// ── Return type ───────────────────────────────────────────────────────────────\n\nexport interface StaffEngine {\n routes: Router;\n auth: AuthMiddleware;\n staff: StaffService;\n authService: AuthService;\n permissions: PermissionService;\n models: {\n Staff: Model<IStaffDocument>;\n PermissionGroup: Model<IPermissionGroupDocument>;\n };\n destroy: () => Promise<void>;\n}\n\n// ── Factory ───────────────────────────────────────────────────────────────────\n\nexport function createStaffEngine(config: StaffEngineConfig): StaffEngine {\n // 1. Validate config with Zod\n const parseResult = StaffEngineConfigSchema.safeParse(config);\n if (!parseResult.success) {\n const issues = parseResult.error.issues\n .map((i) => `${i.path.join('.')}: ${i.message}`)\n .join(', ');\n throw new InvalidConfigError('config', issues);\n }\n\n // 2. Resolve options\n const resolvedOptions: ResolvedOptions = {\n requireEmailUniqueness:\n config.options?.requireEmailUniqueness ?? DEFAULT_OPTIONS.requireEmailUniqueness,\n allowSelfPasswordChange:\n config.options?.allowSelfPasswordChange ?? DEFAULT_OPTIONS.allowSelfPasswordChange,\n rateLimiter: {\n windowMs:\n config.options?.rateLimiter?.windowMs ?? DEFAULT_OPTIONS.rateLimiter.windowMs,\n maxAttempts:\n config.options?.rateLimiter?.maxAttempts ?? DEFAULT_OPTIONS.rateLimiter.maxAttempts,\n },\n };\n\n const resolvedAuth = {\n jwtSecret: config.auth.jwtSecret,\n staffTokenExpiry: config.auth.staffTokenExpiry ?? DEFAULT_AUTH.staffTokenExpiry,\n ownerTokenExpiry: config.auth.ownerTokenExpiry ?? DEFAULT_AUTH.ownerTokenExpiry,\n permissionCacheTtlMs: config.auth.permissionCacheTtlMs ?? DEFAULT_AUTH.permissionCacheTtlMs,\n };\n\n // 3. Set up logger\n const logger = config.logger ?? noopLogger;\n\n // 4. Register mongoose models\n const conn = config.db.connection as import('mongoose').Connection;\n const prefix = config.db.collectionPrefix;\n\n const StaffModel = createStaffModel(conn, prefix);\n const PermissionGroupModel = createPermissionGroupModel(conn, prefix);\n\n // 5. Create services (dependency order)\n const redis = config.redis?.connection ?? null;\n const keyPrefix = config.redis?.keyPrefix ?? 'staff:';\n\n const rateLimiter = new RateLimiterService(\n resolvedOptions.rateLimiter.windowMs,\n resolvedOptions.rateLimiter.maxAttempts,\n redis,\n keyPrefix,\n logger,\n );\n\n const permissionCache = new PermissionCacheService(\n StaffModel,\n resolvedAuth.permissionCacheTtlMs,\n redis,\n keyPrefix,\n logger,\n config.tenantId,\n );\n\n const permissionService = new PermissionService(\n PermissionGroupModel,\n permissionCache,\n logger,\n config.tenantId,\n );\n\n const staffService = new StaffService({\n Staff: StaffModel,\n PermissionGroup: PermissionGroupModel,\n adapters: config.adapters,\n hooks: config.hooks ?? {},\n permissionCache,\n logger,\n tenantId: config.tenantId,\n requireEmailUniqueness: resolvedOptions.requireEmailUniqueness,\n });\n\n const authService = new AuthService({\n Staff: StaffModel,\n adapters: config.adapters,\n hooks: config.hooks ?? {},\n rateLimiter,\n logger,\n tenantId: config.tenantId,\n jwtSecret: resolvedAuth.jwtSecret,\n staffTokenExpiry: resolvedAuth.staffTokenExpiry,\n ownerTokenExpiry: resolvedAuth.ownerTokenExpiry,\n allowSelfPasswordChange: resolvedOptions.allowSelfPasswordChange,\n });\n\n // 6. Create auth middleware\n const auth = createAuthMiddleware(\n resolvedAuth.jwtSecret,\n permissionCache,\n StaffModel,\n logger,\n config.tenantId,\n );\n\n // 7. Create routes\n const routes = createRoutes(\n { staff: staffService, auth: authService, permissions: permissionService },\n auth,\n logger,\n resolvedOptions.allowSelfPasswordChange,\n );\n\n // 8. Return engine object\n async function destroy(): Promise<void> {\n await permissionCache.invalidateAll();\n logger.info('StaffEngine destroyed');\n }\n\n return {\n routes,\n auth,\n staff: staffService,\n authService,\n permissions: permissionService,\n models: { Staff: StaffModel, PermissionGroup: PermissionGroupModel },\n destroy,\n };\n}\n\n// ── Barrel re-exports ─────────────────────────────────────────────────────────\n\nexport * from './constants/index.js';\nexport * from './errors/index.js';\nexport * from './schemas/index.js';\nexport * from './services/index.js';\nexport * from './validation/index.js';\nexport * from './middleware/auth.middleware.js';\nexport * from './utils/error-handler.js';\nexport { createRoutes } from './routes/index.js';\nexport type { StaffEngineConfig, ResolvedOptions } from '@astralibx/staff-types';\nexport { DEFAULT_OPTIONS } from '@astralibx/staff-types';\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/schemas/staff.schema.ts","../src/schemas/permission-group.schema.ts","../src/services/rate-limiter.service.ts","../src/services/permission-cache.service.ts","../src/constants/index.ts","../src/errors/index.ts","../src/services/permission.service.ts","../src/validation/permissions.ts","../src/validation/config.schema.ts","../src/services/staff.service.ts","../src/services/auth.service.ts","../src/middleware/auth.middleware.ts","../src/utils/error-handler.ts","../src/routes/auth.routes.ts","../src/routes/staff.routes.ts","../src/routes/permission-group.routes.ts","../src/routes/index.ts","../src/index.ts"],"names":["Schema","STAFF_ROLE_VALUES","STAFF_STATUS_VALUES","STAFF_STATUS","PERMISSION_TYPE_VALUES","AlxError","PERMISSION_TYPE","z","STAFF_ROLE","jwt","sendError","Router","sendSuccess","DEFAULT_OPTIONS","noopLogger"],"mappings":"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","file":"index.cjs","sourcesContent":["import { Schema, type Connection, type Model, type Document, type Types } from 'mongoose';\nimport { STAFF_ROLE_VALUES, STAFF_STATUS_VALUES, STAFF_STATUS } from '@astralibx/staff-types';\nimport type { IStaff } from '@astralibx/staff-types';\n\nexport interface IStaffDocument extends Omit<IStaff, '_id'>, Document {\n _id: Types.ObjectId;\n}\n\nexport function createStaffModel(connection: Connection, prefix?: string): Model<IStaffDocument> {\n const schema = new Schema<IStaffDocument>(\n {\n name: { type: String, required: true, trim: true },\n email: { type: String, required: true, trim: true, lowercase: true },\n password: { type: String, required: true, select: false },\n role: { type: String, enum: STAFF_ROLE_VALUES, default: 'staff' },\n status: { type: String, enum: STAFF_STATUS_VALUES, default: STAFF_STATUS.Pending },\n permissions: { type: [String], default: [] },\n externalUserId: { type: String, sparse: true },\n lastLoginAt: { type: Date },\n lastLoginIp: { type: String },\n metadata: { type: Schema.Types.Mixed },\n tenantId: { type: String, sparse: true },\n },\n { timestamps: true },\n );\n\n schema.index({ email: 1, tenantId: 1 }, { unique: true });\n schema.index({ status: 1 });\n schema.index({ role: 1 });\n\n const collectionName = prefix ? `${prefix}_staff` : 'staff';\n return connection.model<IStaffDocument>('Staff', schema, collectionName);\n}\n","import { Schema, type Connection, type Model, type Document, type Types } from 'mongoose';\nimport { PERMISSION_TYPE_VALUES } from '@astralibx/staff-types';\nimport type { IPermissionGroup } from '@astralibx/staff-types';\n\nexport interface IPermissionGroupDocument extends Omit<IPermissionGroup, '_id'>, Document {\n _id: Types.ObjectId;\n}\n\nconst permissionEntrySchema = new Schema(\n {\n key: { type: String, required: true },\n label: { type: String, required: true },\n type: { type: String, enum: PERMISSION_TYPE_VALUES, required: true },\n },\n { _id: false },\n);\n\nexport function createPermissionGroupModel(\n connection: Connection,\n prefix?: string,\n): Model<IPermissionGroupDocument> {\n const schema = new Schema<IPermissionGroupDocument>(\n {\n groupId: { type: String, required: true },\n label: { type: String, required: true, trim: true },\n permissions: { type: [permissionEntrySchema], default: [] },\n sortOrder: { type: Number, default: 0 },\n tenantId: { type: String, index: true, sparse: true },\n },\n { timestamps: true },\n );\n\n schema.index({ groupId: 1, tenantId: 1 }, { unique: true });\n schema.index({ sortOrder: 1 });\n\n const collectionName = prefix ? `${prefix}_permission_groups` : 'permission_groups';\n return connection.model<IPermissionGroupDocument>('PermissionGroup', schema, collectionName);\n}\n","import type { LogAdapter } from '@astralibx/staff-types';\n\ninterface RateLimitEntry {\n count: number;\n expiresAt: number;\n}\n\nexport class RateLimiterService {\n private memoryStore = new Map<string, RateLimitEntry>();\n\n constructor(\n private windowMs: number,\n private maxAttempts: number,\n private redis: unknown | null,\n private keyPrefix: string,\n private logger: LogAdapter,\n ) {}\n\n async checkLimit(key: string): Promise<{ allowed: boolean; remaining: number; retryAfterMs?: number }> {\n if (this.redis) {\n return this.checkLimitRedis(key);\n }\n return this.checkLimitMemory(key);\n }\n\n async recordAttempt(key: string): Promise<void> {\n if (this.redis) {\n return this.recordAttemptRedis(key);\n }\n this.recordAttemptMemory(key);\n }\n\n async reset(key: string): Promise<void> {\n if (this.redis) {\n await (this.redis as any).del(`${this.keyPrefix}rate:${key}`);\n return;\n }\n this.memoryStore.delete(key);\n }\n\n private checkLimitMemory(key: string): { allowed: boolean; remaining: number; retryAfterMs?: number } {\n const entry = this.memoryStore.get(key);\n if (!entry || Date.now() > entry.expiresAt) {\n return { allowed: true, remaining: this.maxAttempts };\n }\n if (entry.count >= this.maxAttempts) {\n return { allowed: false, remaining: 0, retryAfterMs: entry.expiresAt - Date.now() };\n }\n return { allowed: true, remaining: this.maxAttempts - entry.count };\n }\n\n private recordAttemptMemory(key: string): void {\n const entry = this.memoryStore.get(key);\n if (!entry || Date.now() > entry.expiresAt) {\n this.memoryStore.set(key, { count: 1, expiresAt: Date.now() + this.windowMs });\n } else {\n entry.count++;\n }\n }\n\n private async checkLimitRedis(key: string): Promise<{ allowed: boolean; remaining: number; retryAfterMs?: number }> {\n const redisKey = `${this.keyPrefix}rate:${key}`;\n const redis = this.redis as any;\n const count = await redis.get(redisKey);\n const current = count ? parseInt(count, 10) : 0;\n if (current >= this.maxAttempts) {\n const ttl = await redis.pttl(redisKey);\n return { allowed: false, remaining: 0, retryAfterMs: ttl > 0 ? ttl : this.windowMs };\n }\n return { allowed: true, remaining: this.maxAttempts - current };\n }\n\n private async recordAttemptRedis(key: string): Promise<void> {\n const redisKey = `${this.keyPrefix}rate:${key}`;\n const redis = this.redis as any;\n const count = await redis.incr(redisKey);\n if (count === 1) {\n await redis.pexpire(redisKey, this.windowMs);\n }\n }\n}\n","import type { Model } from 'mongoose';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport type { IStaffDocument } from '../schemas/staff.schema.js';\n\nexport class PermissionCacheService {\n private memoryCache = new Map<string, { permissions: string[]; expiresAt: number }>();\n\n constructor(\n private StaffModel: Model<IStaffDocument>,\n private ttlMs: number,\n private redis: unknown | null,\n private keyPrefix: string,\n private logger: LogAdapter,\n private tenantId?: string,\n ) {}\n\n async get(staffId: string): Promise<string[]> {\n if (this.redis) {\n return this.getRedis(staffId);\n }\n return this.getMemory(staffId);\n }\n\n async invalidate(staffId: string): Promise<void> {\n if (this.redis) {\n await (this.redis as any).del(`${this.keyPrefix}perms:${staffId}`);\n return;\n }\n this.memoryCache.delete(staffId);\n }\n\n async invalidateAll(): Promise<void> {\n if (this.redis) {\n const redis = this.redis as any;\n const keys = await redis.keys(`${this.keyPrefix}perms:*`);\n if (keys.length > 0) {\n await redis.del(...keys);\n }\n return;\n }\n this.memoryCache.clear();\n }\n\n private async getMemory(staffId: string): Promise<string[]> {\n const cached = this.memoryCache.get(staffId);\n if (cached && Date.now() < cached.expiresAt) {\n return cached.permissions;\n }\n const permissions = await this.fetchFromDb(staffId);\n this.memoryCache.set(staffId, { permissions, expiresAt: Date.now() + this.ttlMs });\n return permissions;\n }\n\n private async getRedis(staffId: string): Promise<string[]> {\n const redisKey = `${this.keyPrefix}perms:${staffId}`;\n const redis = this.redis as any;\n const cached = await redis.get(redisKey);\n if (cached) {\n return JSON.parse(cached);\n }\n const permissions = await this.fetchFromDb(staffId);\n await redis.set(redisKey, JSON.stringify(permissions), 'PX', this.ttlMs);\n return permissions;\n }\n\n private async fetchFromDb(staffId: string): Promise<string[]> {\n const filter: Record<string, unknown> = { _id: staffId };\n if (this.tenantId) filter.tenantId = this.tenantId;\n const staff = await this.StaffModel.findOne(filter).select('permissions').lean();\n return staff?.permissions ?? [];\n }\n}\n","export const ERROR_CODE = {\n // Auth\n InvalidCredentials: 'STAFF_INVALID_CREDENTIALS',\n AccountInactive: 'STAFF_ACCOUNT_INACTIVE',\n AccountPending: 'STAFF_ACCOUNT_PENDING',\n RateLimited: 'STAFF_RATE_LIMITED',\n TokenExpired: 'STAFF_TOKEN_EXPIRED',\n TokenInvalid: 'STAFF_TOKEN_INVALID',\n InsufficientPermissions: 'STAFF_INSUFFICIENT_PERMISSIONS',\n OwnerOnly: 'STAFF_OWNER_ONLY',\n\n // CRUD\n StaffNotFound: 'STAFF_NOT_FOUND',\n EmailExists: 'STAFF_EMAIL_EXISTS',\n SetupAlreadyComplete: 'STAFF_SETUP_ALREADY_COMPLETE',\n LastOwnerGuard: 'STAFF_LAST_OWNER_GUARD',\n InvalidPermissions: 'STAFF_INVALID_PERMISSIONS',\n\n // Permission Groups\n GroupNotFound: 'STAFF_GROUP_NOT_FOUND',\n GroupIdExists: 'STAFF_GROUP_ID_EXISTS',\n\n // Config\n InvalidConfig: 'STAFF_INVALID_CONFIG',\n} as const;\n\nexport type ErrorCode = (typeof ERROR_CODE)[keyof typeof ERROR_CODE];\n\nexport const ERROR_MESSAGE = {\n InvalidCredentials: 'Invalid email or password',\n AccountInactive: 'Account is deactivated',\n AccountPending: 'Account is pending activation',\n RateLimited: 'Too many login attempts. Please try again later.',\n TokenExpired: 'Token has expired',\n TokenInvalid: 'Invalid token',\n InsufficientPermissions: 'Insufficient permissions',\n OwnerOnly: 'This action requires owner privileges',\n StaffNotFound: 'Staff member not found',\n EmailExists: 'A staff member with this email already exists',\n SetupAlreadyComplete: 'Initial setup has already been completed',\n LastOwnerGuard: 'Cannot deactivate the last active owner',\n InvalidPermissions: 'Edit permissions require corresponding view permissions',\n GroupNotFound: 'Permission group not found',\n GroupIdExists: 'A permission group with this ID already exists',\n InvalidConfig: 'Invalid engine configuration',\n} as const;\n\nexport const DEFAULTS = {\n ListPageSize: 20,\n MaxListPageSize: 100,\n PermissionCacheTtlMs: 5 * 60 * 1000,\n} as const;\n\nexport const DEFAULT_AUTH = {\n staffTokenExpiry: '24h',\n ownerTokenExpiry: '30d',\n permissionCacheTtlMs: 5 * 60 * 1000,\n} as const;\n","import { AlxError } from '@astralibx/core';\nimport { ERROR_CODE, ERROR_MESSAGE } from '../constants/index.js';\n\nexport class AlxStaffError extends AlxError {\n constructor(\n message: string,\n code: string,\n public readonly context?: Record<string, unknown>,\n ) {\n super(message, code);\n this.name = 'AlxStaffError';\n }\n}\n\nexport class AuthenticationError extends AlxStaffError {\n constructor(code: string = ERROR_CODE.InvalidCredentials, message?: string) {\n super(message || ERROR_MESSAGE.InvalidCredentials, code);\n this.name = 'AuthenticationError';\n }\n}\n\nexport class AuthorizationError extends AlxStaffError {\n constructor(code: string = ERROR_CODE.InsufficientPermissions, message?: string) {\n super(message || ERROR_MESSAGE.InsufficientPermissions, code);\n this.name = 'AuthorizationError';\n }\n}\n\nexport class RateLimitError extends AlxStaffError {\n constructor(public readonly retryAfterMs: number) {\n super(ERROR_MESSAGE.RateLimited, ERROR_CODE.RateLimited, { retryAfterMs });\n this.name = 'RateLimitError';\n }\n}\n\nexport class TokenError extends AlxStaffError {\n constructor(code: string = ERROR_CODE.TokenInvalid, message?: string) {\n super(message || ERROR_MESSAGE.TokenInvalid, code);\n this.name = 'TokenError';\n }\n}\n\nexport class StaffNotFoundError extends AlxStaffError {\n constructor(public readonly staffId: string) {\n super(ERROR_MESSAGE.StaffNotFound, ERROR_CODE.StaffNotFound, { staffId });\n this.name = 'StaffNotFoundError';\n }\n}\n\nexport class DuplicateError extends AlxStaffError {\n constructor(code: string, message: string, context?: Record<string, unknown>) {\n super(message, code, context);\n this.name = 'DuplicateError';\n }\n}\n\nexport class SetupError extends AlxStaffError {\n constructor() {\n super(ERROR_MESSAGE.SetupAlreadyComplete, ERROR_CODE.SetupAlreadyComplete);\n this.name = 'SetupError';\n }\n}\n\nexport class LastOwnerError extends AlxStaffError {\n constructor(public readonly staffId: string) {\n super(ERROR_MESSAGE.LastOwnerGuard, ERROR_CODE.LastOwnerGuard, { staffId });\n this.name = 'LastOwnerError';\n }\n}\n\nexport class InvalidPermissionError extends AlxStaffError {\n constructor(public readonly missingViewKeys: string[]) {\n super(ERROR_MESSAGE.InvalidPermissions, ERROR_CODE.InvalidPermissions, { missingViewKeys });\n this.name = 'InvalidPermissionError';\n }\n}\n\nexport class GroupNotFoundError extends AlxStaffError {\n constructor(public readonly groupId: string) {\n super(ERROR_MESSAGE.GroupNotFound, ERROR_CODE.GroupNotFound, { groupId });\n this.name = 'GroupNotFoundError';\n }\n}\n\nexport class InvalidConfigError extends AlxStaffError {\n constructor(public readonly field: string, public readonly reason: string) {\n super(`Invalid config for \"${field}\": ${reason}`, ERROR_CODE.InvalidConfig, { field, reason });\n this.name = 'InvalidConfigError';\n }\n}\n","import type { Model } from 'mongoose';\nimport type { LogAdapter, IPermissionGroupCreateInput, IPermissionGroupUpdateInput } from '@astralibx/staff-types';\nimport type { IPermissionGroupDocument } from '../schemas/permission-group.schema.js';\nimport { DuplicateError, GroupNotFoundError } from '../errors/index.js';\nimport { ERROR_CODE, ERROR_MESSAGE } from '../constants/index.js';\nimport type { PermissionCacheService } from './permission-cache.service.js';\n\nexport class PermissionService {\n constructor(\n private PermissionGroup: Model<IPermissionGroupDocument>,\n private permissionCache: PermissionCacheService,\n private logger: LogAdapter,\n private tenantId?: string,\n ) {}\n\n private get tenantFilter(): Record<string, unknown> {\n return this.tenantId ? { tenantId: this.tenantId } : {};\n }\n\n async listGroups(): Promise<IPermissionGroupDocument[]> {\n return this.PermissionGroup.find(this.tenantFilter).sort({ sortOrder: 1 }).lean() as unknown as IPermissionGroupDocument[];\n }\n\n async createGroup(data: IPermissionGroupCreateInput): Promise<IPermissionGroupDocument> {\n const existing = await this.PermissionGroup.findOne({\n groupId: data.groupId,\n ...this.tenantFilter,\n });\n if (existing) {\n throw new DuplicateError(\n ERROR_CODE.GroupIdExists,\n ERROR_MESSAGE.GroupIdExists,\n { groupId: data.groupId },\n );\n }\n const group = await this.PermissionGroup.create({\n ...data,\n sortOrder: data.sortOrder ?? 0,\n ...this.tenantFilter,\n });\n this.logger.info('Permission group created', { groupId: data.groupId });\n return group.toObject();\n }\n\n async updateGroup(groupId: string, data: IPermissionGroupUpdateInput): Promise<IPermissionGroupDocument> {\n const group = await this.PermissionGroup.findOneAndUpdate(\n { groupId, ...this.tenantFilter },\n { $set: data },\n { new: true },\n ).lean();\n if (!group) {\n throw new GroupNotFoundError(groupId);\n }\n await this.permissionCache.invalidateAll();\n this.logger.info('Permission group updated', { groupId, fields: Object.keys(data) });\n return group as unknown as IPermissionGroupDocument;\n }\n\n async deleteGroup(groupId: string): Promise<void> {\n const result = await this.PermissionGroup.deleteOne({ groupId, ...this.tenantFilter });\n if (result.deletedCount === 0) {\n throw new GroupNotFoundError(groupId);\n }\n await this.permissionCache.invalidateAll();\n this.logger.info('Permission group deleted', { groupId });\n }\n\n async getAllPermissionKeys(): Promise<string[]> {\n const groups = await this.listGroups();\n return groups.flatMap(g => g.permissions.map(p => p.key));\n }\n}\n","import { PERMISSION_TYPE } from '@astralibx/staff-types';\nimport { InvalidPermissionError } from '../errors/index.js';\nimport type { IPermissionGroupDocument } from '../schemas/permission-group.schema.js';\n\n/**\n * Validates that for every edit-type permission, the corresponding view-type permission\n * is also present. Single-level cascade only.\n * Example: 'chat:edit' requires 'chat:view'\n */\nexport function validatePermissionPairs(\n permissions: string[],\n allGroups: IPermissionGroupDocument[],\n): void {\n const allEntries = allGroups.flatMap(g => g.permissions);\n const editKeys = allEntries\n .filter(e => e.type === PERMISSION_TYPE.Edit)\n .map(e => e.key);\n\n const permissionSet = new Set(permissions);\n const missingViewKeys: string[] = [];\n\n for (const editKey of editKeys) {\n if (!permissionSet.has(editKey)) continue;\n const prefix = editKey.substring(0, editKey.lastIndexOf(':'));\n const viewKey = `${prefix}:view`;\n const viewEntry = allEntries.find(e => e.key === viewKey && e.type === PERMISSION_TYPE.View);\n if (viewEntry && !permissionSet.has(viewKey)) {\n missingViewKeys.push(viewKey);\n }\n }\n\n if (missingViewKeys.length > 0) {\n throw new InvalidPermissionError(missingViewKeys);\n }\n}\n","import { z } from 'zod';\n\nexport const StaffEngineConfigSchema = z.object({\n db: z.object({\n connection: z.unknown().refine((v) => v !== undefined && v !== null, {\n message: 'db.connection is required',\n }),\n collectionPrefix: z.string().optional(),\n }),\n redis: z\n .object({\n connection: z.unknown(),\n keyPrefix: z.string().optional(),\n })\n .optional(),\n logger: z\n .object({\n info: z.function(),\n warn: z.function(),\n error: z.function(),\n })\n .optional(),\n tenantId: z.string().optional(),\n auth: z.object({\n jwtSecret: z.string().min(1),\n staffTokenExpiry: z.string().optional(),\n ownerTokenExpiry: z.string().optional(),\n permissionCacheTtlMs: z.number().int().positive().optional(),\n }),\n adapters: z.object({\n hashPassword: z.function(),\n comparePassword: z.function(),\n }),\n hooks: z\n .object({\n onStaffCreated: z.function().optional(),\n onLogin: z.function().optional(),\n onLoginFailed: z.function().optional(),\n onPermissionsChanged: z.function().optional(),\n onStatusChanged: z.function().optional(),\n onMetric: z.function().optional(),\n })\n .optional(),\n options: z\n .object({\n requireEmailUniqueness: z.boolean().optional(),\n allowSelfPasswordChange: z.boolean().optional(),\n rateLimiter: z\n .object({\n windowMs: z.number().int().positive().optional(),\n maxAttempts: z.number().int().positive().optional(),\n })\n .optional(),\n })\n .optional(),\n});\n","import type { Model } from 'mongoose';\nimport type {\n LogAdapter, StaffHooks, StaffAdapters, IStaffCreateInput,\n IStaffUpdateInput, IStaffListFilters, IPaginatedResult,\n} from '@astralibx/staff-types';\nimport { STAFF_ROLE, STAFF_STATUS } from '@astralibx/staff-types';\nimport type { IStaffDocument } from '../schemas/staff.schema.js';\nimport type { IPermissionGroupDocument } from '../schemas/permission-group.schema.js';\nimport type { PermissionCacheService } from './permission-cache.service.js';\nimport {\n DuplicateError, StaffNotFoundError,\n LastOwnerError,\n} from '../errors/index.js';\nimport { ERROR_CODE, ERROR_MESSAGE, DEFAULTS } from '../constants/index.js';\nimport { validatePermissionPairs } from '../validation/index.js';\n\nexport interface StaffServiceDeps {\n Staff: Model<IStaffDocument>;\n PermissionGroup: Model<IPermissionGroupDocument>;\n adapters: StaffAdapters;\n hooks: StaffHooks;\n permissionCache: PermissionCacheService;\n logger: LogAdapter;\n tenantId?: string;\n requireEmailUniqueness: boolean;\n}\n\nexport class StaffService {\n private Staff: Model<IStaffDocument>;\n private PermissionGroup: Model<IPermissionGroupDocument>;\n private adapters: StaffAdapters;\n private hooks: StaffHooks;\n private permissionCache: PermissionCacheService;\n private logger: LogAdapter;\n private tenantId?: string;\n private requireEmailUniqueness: boolean;\n\n constructor(deps: StaffServiceDeps) {\n this.Staff = deps.Staff;\n this.PermissionGroup = deps.PermissionGroup;\n this.adapters = deps.adapters;\n this.hooks = deps.hooks;\n this.permissionCache = deps.permissionCache;\n this.logger = deps.logger;\n this.tenantId = deps.tenantId;\n this.requireEmailUniqueness = deps.requireEmailUniqueness;\n }\n\n private get tenantFilter(): Record<string, unknown> {\n return this.tenantId ? { tenantId: this.tenantId } : {};\n }\n\n async create(data: IStaffCreateInput): Promise<IStaffDocument> {\n if (this.requireEmailUniqueness) {\n const existing = await this.Staff.findOne({\n email: data.email.toLowerCase().trim(),\n ...this.tenantFilter,\n });\n if (existing) {\n throw new DuplicateError(ERROR_CODE.EmailExists, ERROR_MESSAGE.EmailExists, { email: data.email });\n }\n }\n\n const hashedPassword = await this.adapters.hashPassword(data.password);\n const staff = await this.Staff.create({\n ...data,\n email: data.email.toLowerCase().trim(),\n password: hashedPassword,\n role: data.role ?? STAFF_ROLE.Staff,\n status: data.status ?? STAFF_STATUS.Pending,\n permissions: data.permissions ?? [],\n ...this.tenantFilter,\n });\n\n this.logger.info('Staff created', { staffId: staff._id.toString() });\n this.hooks.onStaffCreated?.(staff.toObject());\n return staff.toObject();\n }\n\n async list(filters: IStaffListFilters = {}): Promise<IPaginatedResult<IStaffDocument>> {\n const page = Math.max(1, filters.page ?? 1);\n const limit = Math.min(filters.limit ?? DEFAULTS.ListPageSize, DEFAULTS.MaxListPageSize);\n\n const query: Record<string, unknown> = { ...this.tenantFilter };\n if (filters.status) query.status = filters.status;\n if (filters.role) query.role = filters.role;\n\n const [data, total] = await Promise.all([\n this.Staff.find(query)\n .sort({ createdAt: -1 })\n .skip((page - 1) * limit)\n .limit(limit)\n .lean(),\n this.Staff.countDocuments(query),\n ]);\n\n return {\n data: data as unknown as IStaffDocument[],\n pagination: { page, limit, total, totalPages: Math.ceil(total / limit) },\n };\n }\n\n async getById(staffId: string): Promise<IStaffDocument> {\n const staff = await this.Staff.findOne({ _id: staffId, ...this.tenantFilter }).lean() as unknown as IStaffDocument | null;\n if (!staff) throw new StaffNotFoundError(staffId);\n return staff;\n }\n\n async update(staffId: string, data: IStaffUpdateInput): Promise<IStaffDocument> {\n const updateData: Record<string, unknown> = {};\n if (data.name !== undefined) updateData.name = data.name;\n if (data.email !== undefined) updateData.email = data.email.toLowerCase().trim();\n if (data.metadata !== undefined) updateData.metadata = data.metadata;\n\n if (data.email && this.requireEmailUniqueness) {\n const existing = await this.Staff.findOne({\n email: data.email.toLowerCase().trim(),\n _id: { $ne: staffId },\n ...this.tenantFilter,\n });\n if (existing) {\n throw new DuplicateError(ERROR_CODE.EmailExists, ERROR_MESSAGE.EmailExists, { email: data.email });\n }\n }\n\n const staff = await this.Staff.findOneAndUpdate(\n { _id: staffId, ...this.tenantFilter },\n { $set: updateData },\n { new: true },\n ).lean() as unknown as IStaffDocument | null;\n if (!staff) throw new StaffNotFoundError(staffId);\n\n this.logger.info('Staff updated', { staffId, fields: Object.keys(updateData) });\n return staff;\n }\n\n async updatePermissions(staffId: string, permissions: string[]): Promise<IStaffDocument> {\n const groups = await this.PermissionGroup.find(this.tenantFilter).lean() as unknown as IPermissionGroupDocument[];\n validatePermissionPairs(permissions, groups);\n\n const staff = await this.Staff.findOne({ _id: staffId, ...this.tenantFilter });\n if (!staff) throw new StaffNotFoundError(staffId);\n\n const oldPerms = [...staff.permissions];\n staff.permissions = permissions;\n await staff.save();\n\n await this.permissionCache.invalidate(staffId);\n this.hooks.onPermissionsChanged?.(staffId, oldPerms, permissions);\n this.logger.info('Staff permissions updated', { staffId, count: permissions.length });\n return staff.toObject();\n }\n\n async updateStatus(staffId: string, status: string): Promise<IStaffDocument> {\n const staff = await this.Staff.findOne({ _id: staffId, ...this.tenantFilter });\n if (!staff) throw new StaffNotFoundError(staffId);\n\n if (status === STAFF_STATUS.Inactive && staff.role === STAFF_ROLE.Owner) {\n const activeOwnerCount = await this.Staff.countDocuments({\n role: STAFF_ROLE.Owner,\n status: STAFF_STATUS.Active,\n ...this.tenantFilter,\n });\n if (activeOwnerCount <= 1) throw new LastOwnerError(staffId);\n }\n\n const oldStatus = staff.status;\n staff.status = status as any;\n await staff.save();\n\n await this.permissionCache.invalidate(staffId);\n this.hooks.onStatusChanged?.(staffId, oldStatus, status);\n this.logger.info('Staff status updated', { staffId, oldStatus, newStatus: status });\n return staff.toObject();\n }\n}\n","import jwt from 'jsonwebtoken';\nimport type { Model } from 'mongoose';\nimport type {\n LogAdapter, StaffHooks, StaffAdapters,\n} from '@astralibx/staff-types';\nimport { STAFF_ROLE, STAFF_STATUS } from '@astralibx/staff-types';\nimport type { IStaffDocument } from '../schemas/staff.schema.js';\nimport type { RateLimiterService } from './rate-limiter.service.js';\nimport {\n AuthenticationError, StaffNotFoundError,\n SetupError, RateLimitError,\n} from '../errors/index.js';\nimport { ERROR_CODE, ERROR_MESSAGE } from '../constants/index.js';\n\nexport interface AuthServiceDeps {\n Staff: Model<IStaffDocument>;\n adapters: StaffAdapters;\n hooks: StaffHooks;\n rateLimiter: RateLimiterService;\n logger: LogAdapter;\n tenantId?: string;\n jwtSecret: string;\n staffTokenExpiry: string;\n ownerTokenExpiry: string;\n allowSelfPasswordChange: boolean;\n}\n\nexport class AuthService {\n private Staff: Model<IStaffDocument>;\n private adapters: StaffAdapters;\n private hooks: StaffHooks;\n private rateLimiter: RateLimiterService;\n private logger: LogAdapter;\n private tenantId?: string;\n private jwtSecret: string;\n private staffTokenExpiry: string;\n private ownerTokenExpiry: string;\n private allowSelfPasswordChange: boolean;\n\n constructor(deps: AuthServiceDeps) {\n this.Staff = deps.Staff;\n this.adapters = deps.adapters;\n this.hooks = deps.hooks;\n this.rateLimiter = deps.rateLimiter;\n this.logger = deps.logger;\n this.tenantId = deps.tenantId;\n this.jwtSecret = deps.jwtSecret;\n this.staffTokenExpiry = deps.staffTokenExpiry;\n this.ownerTokenExpiry = deps.ownerTokenExpiry;\n this.allowSelfPasswordChange = deps.allowSelfPasswordChange;\n }\n\n private get tenantFilter(): Record<string, unknown> {\n return this.tenantId ? { tenantId: this.tenantId } : {};\n }\n\n generateToken(staffId: string, role: string): string {\n const expiresIn = role === STAFF_ROLE.Owner ? this.ownerTokenExpiry : this.staffTokenExpiry;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return jwt.sign({ staffId, role }, this.jwtSecret, { expiresIn } as any);\n }\n\n async setupOwner(data: { name: string; email: string; password: string }): Promise<{ staff: IStaffDocument; token: string }> {\n // Race-safe: check count first, then create. If two requests race past the\n // count check, the unique index on {email, tenantId} will reject the second\n // create, which we catch and convert to SetupError.\n const count = await this.Staff.countDocuments(this.tenantFilter);\n if (count > 0) throw new SetupError();\n\n const hashedPassword = await this.adapters.hashPassword(data.password);\n let staff: IStaffDocument;\n try {\n const doc = await this.Staff.create({\n name: data.name,\n email: data.email.toLowerCase().trim(),\n password: hashedPassword,\n role: STAFF_ROLE.Owner,\n status: STAFF_STATUS.Active,\n permissions: [],\n ...this.tenantFilter,\n });\n staff = doc.toObject() as unknown as IStaffDocument;\n } catch (err: unknown) {\n // Race condition: another request created a staff member between our count and create\n if (err && typeof err === 'object' && 'code' in err && (err as any).code === 11000) {\n throw new SetupError();\n }\n throw err;\n }\n const token = this.generateToken(staff._id.toString(), STAFF_ROLE.Owner);\n this.logger.info('Owner setup complete', { staffId: staff._id.toString() });\n this.hooks.onStaffCreated?.(staff);\n this.hooks.onMetric?.({ name: 'staff_setup_complete', value: 1 });\n return { staff, token };\n }\n\n async login(email: string, password: string, ip?: string): Promise<{ staff: IStaffDocument; token: string }> {\n if (ip) {\n const limit = await this.rateLimiter.checkLimit(ip);\n if (!limit.allowed) {\n this.hooks.onLoginFailed?.(email, ip);\n throw new RateLimitError(limit.retryAfterMs!);\n }\n }\n\n const staff = await this.Staff.findOne({\n email: email.toLowerCase().trim(),\n ...this.tenantFilter,\n }).select('+password');\n\n if (!staff) {\n if (ip) await this.rateLimiter.recordAttempt(ip);\n this.hooks.onLoginFailed?.(email, ip);\n throw new AuthenticationError(ERROR_CODE.InvalidCredentials);\n }\n\n const valid = await this.adapters.comparePassword(password, staff.password);\n if (!valid) {\n if (ip) await this.rateLimiter.recordAttempt(ip);\n this.hooks.onLoginFailed?.(email, ip);\n throw new AuthenticationError(ERROR_CODE.InvalidCredentials);\n }\n\n if (staff.status === STAFF_STATUS.Inactive) {\n throw new AuthenticationError(ERROR_CODE.AccountInactive, ERROR_MESSAGE.AccountInactive);\n }\n if (staff.status === STAFF_STATUS.Pending) {\n throw new AuthenticationError(ERROR_CODE.AccountPending, ERROR_MESSAGE.AccountPending);\n }\n\n staff.lastLoginAt = new Date();\n if (ip) staff.lastLoginIp = ip;\n await staff.save();\n\n if (ip) await this.rateLimiter.reset(ip);\n const token = this.generateToken(staff._id.toString(), staff.role);\n this.hooks.onLogin?.(staff.toObject(), ip);\n this.hooks.onMetric?.({ name: 'staff_login', value: 1, labels: { role: staff.role } });\n this.logger.info('Staff login', { staffId: staff._id.toString() });\n\n const staffObj = staff.toObject();\n delete (staffObj as any).password;\n return { staff: staffObj, token };\n }\n\n async resetPassword(staffId: string, newPassword: string): Promise<void> {\n const staff = await this.Staff.findOne({ _id: staffId, ...this.tenantFilter });\n if (!staff) throw new StaffNotFoundError(staffId);\n\n staff.password = await this.adapters.hashPassword(newPassword);\n await staff.save();\n this.logger.info('Staff password reset', { staffId });\n }\n\n async changeOwnPassword(staffId: string, oldPassword: string, newPassword: string): Promise<void> {\n if (!this.allowSelfPasswordChange) {\n throw new AuthenticationError(ERROR_CODE.InsufficientPermissions, 'Self password change is disabled');\n }\n\n const staff = await this.Staff.findOne({ _id: staffId, ...this.tenantFilter }).select('+password');\n if (!staff) throw new StaffNotFoundError(staffId);\n\n const valid = await this.adapters.comparePassword(oldPassword, staff.password);\n if (!valid) throw new AuthenticationError(ERROR_CODE.InvalidCredentials, 'Current password is incorrect');\n\n staff.password = await this.adapters.hashPassword(newPassword);\n await staff.save();\n this.logger.info('Staff changed own password', { staffId });\n }\n}\n","import jwt from 'jsonwebtoken';\nimport type { Request, Response, NextFunction, RequestHandler } from 'express';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport { STAFF_ROLE, STAFF_STATUS } from '@astralibx/staff-types';\nimport type { PermissionCacheService } from '../services/permission-cache.service.js';\nimport type { IStaffDocument } from '../schemas/staff.schema.js';\nimport type { Model } from 'mongoose';\nimport { TokenError, AuthorizationError } from '../errors/index.js';\nimport { ERROR_CODE, ERROR_MESSAGE } from '../constants/index.js';\n\nexport interface StaffUser {\n staffId: string;\n name: string;\n email: string;\n role: string;\n permissions: string[];\n}\n\nexport interface AuthenticatedRequest extends Request {\n user: StaffUser;\n}\n\nexport interface AuthMiddleware {\n verifyToken: RequestHandler;\n resolveStaff: (token: string) => Promise<StaffUser | null>;\n requirePermission: (...keys: string[]) => RequestHandler;\n ownerOnly: RequestHandler;\n requireRole: (...roles: string[]) => RequestHandler;\n}\n\nexport function createAuthMiddleware(\n jwtSecret: string,\n permissionCache: PermissionCacheService,\n StaffModel: Model<IStaffDocument>,\n logger: LogAdapter,\n tenantId?: string,\n): AuthMiddleware {\n\n async function resolveStaffFromToken(token: string): Promise<StaffUser | null> {\n try {\n const payload = jwt.verify(token, jwtSecret) as { staffId: string; role: string };\n if (!payload.staffId || !payload.role) return null;\n\n // Check staff status\n const filter: Record<string, unknown> = { _id: payload.staffId };\n if (tenantId) filter.tenantId = tenantId;\n const staff = await StaffModel.findOne(filter).select('name email status role').lean() as IStaffDocument | null;\n if (!staff) return null;\n if (staff.status !== STAFF_STATUS.Active) return null;\n\n const permissions = await permissionCache.get(payload.staffId);\n return { staffId: payload.staffId, name: staff.name, email: staff.email, role: staff.role, permissions };\n } catch {\n return null;\n }\n }\n\n const verifyToken: RequestHandler = async (req: Request, res: Response, next: NextFunction) => {\n const authHeader = req.headers.authorization;\n if (!authHeader?.startsWith('Bearer ')) {\n res.status(401).json({ success: false, error: ERROR_MESSAGE.TokenInvalid, code: ERROR_CODE.TokenInvalid });\n return;\n }\n\n const token = authHeader.slice(7);\n\n // Distinguish expired vs invalid tokens before full resolution\n try {\n jwt.verify(token, jwtSecret);\n } catch (err: unknown) {\n if (err instanceof jwt.TokenExpiredError) {\n res.status(401).json({ success: false, error: ERROR_MESSAGE.TokenExpired, code: ERROR_CODE.TokenExpired });\n return;\n }\n res.status(401).json({ success: false, error: ERROR_MESSAGE.TokenInvalid, code: ERROR_CODE.TokenInvalid });\n return;\n }\n\n const user = await resolveStaffFromToken(token);\n if (!user) {\n res.status(401).json({ success: false, error: ERROR_MESSAGE.TokenInvalid, code: ERROR_CODE.TokenInvalid });\n return;\n }\n\n (req as AuthenticatedRequest).user = user;\n next();\n };\n\n function requirePermission(...keys: string[]): RequestHandler {\n return (req: Request, res: Response, next: NextFunction) => {\n const user = (req as AuthenticatedRequest).user;\n if (!user) {\n res.status(401).json({ success: false, error: ERROR_MESSAGE.TokenInvalid, code: ERROR_CODE.TokenInvalid });\n return;\n }\n\n // Owner bypasses permission checks\n if (user.role === STAFF_ROLE.Owner) {\n next();\n return;\n }\n\n const permSet = new Set(user.permissions);\n const missing: string[] = [];\n\n for (const key of keys) {\n if (!permSet.has(key)) {\n missing.push(key);\n continue;\n }\n // Single-level edit→view cascade\n if (key.endsWith(':edit')) {\n const prefix = key.substring(0, key.lastIndexOf(':'));\n const viewKey = `${prefix}:view`;\n if (!permSet.has(viewKey)) {\n missing.push(viewKey);\n }\n }\n }\n\n if (missing.length > 0) {\n res.status(403).json({\n success: false,\n error: ERROR_MESSAGE.InsufficientPermissions,\n code: ERROR_CODE.InsufficientPermissions,\n missing,\n });\n return;\n }\n\n next();\n };\n }\n\n const ownerOnly: RequestHandler = (req: Request, res: Response, next: NextFunction) => {\n const user = (req as AuthenticatedRequest).user;\n if (!user || user.role !== STAFF_ROLE.Owner) {\n res.status(403).json({ success: false, error: ERROR_MESSAGE.OwnerOnly, code: ERROR_CODE.OwnerOnly });\n return;\n }\n next();\n };\n\n function requireRole(...roles: string[]): RequestHandler {\n return (req: Request, res: Response, next: NextFunction) => {\n const user = (req as AuthenticatedRequest).user;\n if (!user || !roles.includes(user.role)) {\n res.status(403).json({ success: false, error: ERROR_MESSAGE.InsufficientPermissions, code: ERROR_CODE.InsufficientPermissions });\n return;\n }\n next();\n };\n }\n\n return {\n verifyToken,\n resolveStaff: resolveStaffFromToken,\n requirePermission,\n ownerOnly,\n requireRole,\n };\n}\n","import type { Response } from 'express';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport { sendSuccess, sendError } from '@astralibx/core';\nimport {\n AlxStaffError, AuthenticationError, AuthorizationError,\n RateLimitError, TokenError, StaffNotFoundError, DuplicateError,\n SetupError, LastOwnerError, InvalidPermissionError, GroupNotFoundError,\n} from '../errors/index.js';\n\nexport { sendSuccess };\n\nfunction sendStaffError(res: Response, error: AlxStaffError, status: number): void {\n res.status(status).json({ success: false, error: error.message, code: error.code });\n}\n\nexport function handleStaffError(res: Response, error: unknown, logger: LogAdapter): void {\n if (error instanceof RateLimitError) {\n res.set('Retry-After', String(Math.ceil(error.retryAfterMs / 1000)));\n sendStaffError(res, error, 429);\n } else if (error instanceof AuthenticationError || error instanceof TokenError) {\n sendStaffError(res, error, 401);\n } else if (error instanceof AuthorizationError || error instanceof SetupError) {\n sendStaffError(res, error, 403);\n } else if (error instanceof StaffNotFoundError || error instanceof GroupNotFoundError) {\n sendStaffError(res, error, 404);\n } else if (error instanceof DuplicateError) {\n sendStaffError(res, error, 409);\n } else if (error instanceof LastOwnerError || error instanceof InvalidPermissionError) {\n sendStaffError(res, error, 400);\n } else if (error instanceof AlxStaffError) {\n sendStaffError(res, error, 400);\n } else {\n const message = error instanceof Error ? error.message : 'Unknown error';\n logger.error('Unexpected error', { error: message });\n sendError(res, message, 500);\n }\n}\n","import { Router } from 'express';\nimport type { Request, Response } from 'express';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport type { StaffService } from '../services/staff.service.js';\nimport type { AuthService } from '../services/auth.service.js';\nimport type { AuthMiddleware, AuthenticatedRequest } from '../middleware/auth.middleware.js';\nimport { sendSuccess, handleStaffError } from '../utils/error-handler.js';\n\nexport function createAuthRoutes(\n staffService: StaffService,\n authService: AuthService,\n auth: AuthMiddleware,\n logger: LogAdapter,\n allowSelfPasswordChange: boolean,\n): Router {\n const router = Router();\n\n // POST /setup — public, creates initial owner account\n router.post('/setup', async (req: Request, res: Response) => {\n try {\n const result = await authService.setupOwner(req.body);\n sendSuccess(res, result, 201);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // POST /login — public, returns staff + token\n router.post('/login', async (req: Request, res: Response) => {\n try {\n const { email, password } = req.body as { email: string; password: string };\n const ip = req.ip || req.socket.remoteAddress || '';\n const result = await authService.login(email, password, ip);\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // GET /me — authenticated, returns current staff profile + permissions\n router.get('/me', auth.verifyToken, async (req: Request, res: Response) => {\n try {\n const user = (req as AuthenticatedRequest).user;\n const staff = await staffService.getById(user.staffId);\n sendSuccess(res, { staff, permissions: user.permissions });\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /me/password — only mounted if allowSelfPasswordChange is true\n if (allowSelfPasswordChange) {\n router.put('/me/password', auth.verifyToken, async (req: Request, res: Response) => {\n try {\n const user = (req as AuthenticatedRequest).user;\n const { oldPassword, newPassword } = req.body as { oldPassword: string; newPassword: string };\n await authService.changeOwnPassword(user.staffId, oldPassword, newPassword);\n sendSuccess(res, { message: 'Password changed successfully' });\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n }\n\n return router;\n}\n","import { Router } from 'express';\nimport type { Request, Response } from 'express';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport type { StaffService } from '../services/staff.service.js';\nimport type { AuthService } from '../services/auth.service.js';\nimport { sendSuccess, handleStaffError } from '../utils/error-handler.js';\n\nexport function createStaffRoutes(\n staffService: StaffService,\n logger: LogAdapter,\n authService?: AuthService,\n): Router {\n const router = Router();\n\n // GET / — list staff\n router.get('/', async (req: Request, res: Response) => {\n try {\n const query = req.query as Record<string, string | undefined>;\n const filters: Record<string, unknown> = {};\n if (query['status']) filters['status'] = query['status'];\n if (query['role']) filters['role'] = query['role'];\n if (query['page']) filters['page'] = parseInt(query['page']!, 10);\n if (query['limit']) filters['limit'] = parseInt(query['limit']!, 10);\n const result = await staffService.list(filters as Parameters<typeof staffService.list>[0]);\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // POST / — create staff member\n router.post('/', async (req: Request, res: Response) => {\n try {\n const result = await staffService.create(req.body);\n sendSuccess(res, result, 201);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /:staffId — update staff member\n router.put('/:staffId', async (req: Request, res: Response) => {\n try {\n const result = await staffService.update(req.params['staffId']!, req.body);\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /:staffId/permissions — update staff permissions\n router.put('/:staffId/permissions', async (req: Request, res: Response) => {\n try {\n const result = await staffService.updatePermissions(\n req.params['staffId']!,\n req.body.permissions,\n );\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /:staffId/status — update staff status\n router.put('/:staffId/status', async (req: Request, res: Response) => {\n try {\n const result = await staffService.updateStatus(\n req.params['staffId']!,\n req.body.status,\n );\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /:staffId/password — reset staff password (owner action)\n router.put('/:staffId/password', async (req: Request, res: Response) => {\n try {\n if (!authService) {\n throw new Error('AuthService not available');\n }\n await authService.resetPassword(req.params['staffId']!, req.body.password);\n sendSuccess(res, { message: 'Password reset successfully' });\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n return router;\n}\n","import { Router } from 'express';\nimport type { Request, Response } from 'express';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport type { PermissionService } from '../services/permission.service.js';\nimport type { AuthMiddleware } from '../middleware/auth.middleware.js';\nimport { sendSuccess, handleStaffError } from '../utils/error-handler.js';\n\nexport function createPermissionGroupRoutes(\n permissionService: PermissionService,\n auth: AuthMiddleware,\n logger: LogAdapter,\n): Router {\n const router = Router();\n\n // GET / — authenticated, list all permission groups\n router.get('/', auth.verifyToken, async (req: Request, res: Response) => {\n try {\n const result = await permissionService.listGroups();\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // POST / — owner only, create permission group\n router.post('/', auth.verifyToken, auth.ownerOnly, async (req: Request, res: Response) => {\n try {\n const result = await permissionService.createGroup(req.body);\n sendSuccess(res, result, 201);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /:groupId — owner only, update permission group\n router.put('/:groupId', auth.verifyToken, auth.ownerOnly, async (req: Request, res: Response) => {\n try {\n const result = await permissionService.updateGroup(req.params['groupId']!, req.body);\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // DELETE /:groupId — owner only, delete permission group\n router.delete('/:groupId', auth.verifyToken, auth.ownerOnly, async (req: Request, res: Response) => {\n try {\n await permissionService.deleteGroup(req.params['groupId']!);\n sendSuccess(res, { message: 'Group deleted successfully' });\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n return router;\n}\n","import { Router } from 'express';\nimport type { StaffService } from '../services/staff.service.js';\nimport type { AuthService } from '../services/auth.service.js';\nimport type { PermissionService } from '../services/permission.service.js';\nimport type { AuthMiddleware } from '../middleware/auth.middleware.js';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport { createAuthRoutes } from './auth.routes.js';\nimport { createStaffRoutes } from './staff.routes.js';\nimport { createPermissionGroupRoutes } from './permission-group.routes.js';\n\nexport interface RouteServices {\n staff: StaffService;\n auth: AuthService;\n permissions: PermissionService;\n}\n\nexport function createRoutes(\n services: RouteServices,\n auth: AuthMiddleware,\n logger: LogAdapter,\n allowSelfPasswordChange: boolean,\n): Router {\n const router = Router();\n\n // Public + authenticated routes (setup, login, /me)\n router.use('/', createAuthRoutes(services.staff, services.auth, auth, logger, allowSelfPasswordChange));\n\n // Owner-only staff CRUD routes\n router.use('/', auth.verifyToken, auth.ownerOnly, createStaffRoutes(services.staff, logger, services.auth));\n\n // Permission group routes (GET is authenticated, CUD is owner-only)\n router.use('/permission-groups', createPermissionGroupRoutes(services.permissions, auth, logger));\n\n return router;\n}\n","import { noopLogger } from '@astralibx/core';\nimport type { Router } from 'express';\nimport type { Model } from 'mongoose';\nimport type { StaffEngineConfig, ResolvedOptions } from '@astralibx/staff-types';\nimport { DEFAULT_OPTIONS } from '@astralibx/staff-types';\nimport { createStaffModel, type IStaffDocument } from './schemas/staff.schema.js';\nimport { createPermissionGroupModel, type IPermissionGroupDocument } from './schemas/permission-group.schema.js';\nimport { RateLimiterService } from './services/rate-limiter.service.js';\nimport { PermissionCacheService } from './services/permission-cache.service.js';\nimport { PermissionService } from './services/permission.service.js';\nimport { StaffService } from './services/staff.service.js';\nimport { AuthService } from './services/auth.service.js';\nimport { createAuthMiddleware, type AuthMiddleware } from './middleware/auth.middleware.js';\nimport { createRoutes } from './routes/index.js';\nimport { DEFAULT_AUTH } from './constants/index.js';\nimport { InvalidConfigError } from './errors/index.js';\nimport { StaffEngineConfigSchema } from './validation/config.schema.js';\n\n// ── Return type ───────────────────────────────────────────────────────────────\n\nexport interface StaffEngine {\n routes: Router;\n auth: AuthMiddleware;\n staff: StaffService;\n authService: AuthService;\n permissions: PermissionService;\n models: {\n Staff: Model<IStaffDocument>;\n PermissionGroup: Model<IPermissionGroupDocument>;\n };\n destroy: () => Promise<void>;\n}\n\n// ── Factory ───────────────────────────────────────────────────────────────────\n\nexport function createStaffEngine(config: StaffEngineConfig): StaffEngine {\n // 1. Validate config with Zod\n const parseResult = StaffEngineConfigSchema.safeParse(config);\n if (!parseResult.success) {\n const issues = parseResult.error.issues\n .map((i) => `${i.path.join('.')}: ${i.message}`)\n .join(', ');\n throw new InvalidConfigError('config', issues);\n }\n\n // 2. Resolve options\n const resolvedOptions: ResolvedOptions = {\n requireEmailUniqueness:\n config.options?.requireEmailUniqueness ?? DEFAULT_OPTIONS.requireEmailUniqueness,\n allowSelfPasswordChange:\n config.options?.allowSelfPasswordChange ?? DEFAULT_OPTIONS.allowSelfPasswordChange,\n rateLimiter: {\n windowMs:\n config.options?.rateLimiter?.windowMs ?? DEFAULT_OPTIONS.rateLimiter.windowMs,\n maxAttempts:\n config.options?.rateLimiter?.maxAttempts ?? DEFAULT_OPTIONS.rateLimiter.maxAttempts,\n },\n };\n\n const resolvedAuth = {\n jwtSecret: config.auth.jwtSecret,\n staffTokenExpiry: config.auth.staffTokenExpiry ?? DEFAULT_AUTH.staffTokenExpiry,\n ownerTokenExpiry: config.auth.ownerTokenExpiry ?? DEFAULT_AUTH.ownerTokenExpiry,\n permissionCacheTtlMs: config.auth.permissionCacheTtlMs ?? DEFAULT_AUTH.permissionCacheTtlMs,\n };\n\n // 3. Set up logger\n const logger = config.logger ?? noopLogger;\n\n // 4. Register mongoose models\n const conn = config.db.connection as import('mongoose').Connection;\n const prefix = config.db.collectionPrefix;\n\n const StaffModel = createStaffModel(conn, prefix);\n const PermissionGroupModel = createPermissionGroupModel(conn, prefix);\n\n // 5. Create services (dependency order)\n const redis = config.redis?.connection ?? null;\n const keyPrefix = config.redis?.keyPrefix ?? 'staff:';\n\n const rateLimiter = new RateLimiterService(\n resolvedOptions.rateLimiter.windowMs,\n resolvedOptions.rateLimiter.maxAttempts,\n redis,\n keyPrefix,\n logger,\n );\n\n const permissionCache = new PermissionCacheService(\n StaffModel,\n resolvedAuth.permissionCacheTtlMs,\n redis,\n keyPrefix,\n logger,\n config.tenantId,\n );\n\n const permissionService = new PermissionService(\n PermissionGroupModel,\n permissionCache,\n logger,\n config.tenantId,\n );\n\n const staffService = new StaffService({\n Staff: StaffModel,\n PermissionGroup: PermissionGroupModel,\n adapters: config.adapters,\n hooks: config.hooks ?? {},\n permissionCache,\n logger,\n tenantId: config.tenantId,\n requireEmailUniqueness: resolvedOptions.requireEmailUniqueness,\n });\n\n const authService = new AuthService({\n Staff: StaffModel,\n adapters: config.adapters,\n hooks: config.hooks ?? {},\n rateLimiter,\n logger,\n tenantId: config.tenantId,\n jwtSecret: resolvedAuth.jwtSecret,\n staffTokenExpiry: resolvedAuth.staffTokenExpiry,\n ownerTokenExpiry: resolvedAuth.ownerTokenExpiry,\n allowSelfPasswordChange: resolvedOptions.allowSelfPasswordChange,\n });\n\n // 6. Create auth middleware\n const auth = createAuthMiddleware(\n resolvedAuth.jwtSecret,\n permissionCache,\n StaffModel,\n logger,\n config.tenantId,\n );\n\n // 7. Create routes\n const routes = createRoutes(\n { staff: staffService, auth: authService, permissions: permissionService },\n auth,\n logger,\n resolvedOptions.allowSelfPasswordChange,\n );\n\n // 8. Return engine object\n async function destroy(): Promise<void> {\n await permissionCache.invalidateAll();\n logger.info('StaffEngine destroyed');\n }\n\n return {\n routes,\n auth,\n staff: staffService,\n authService,\n permissions: permissionService,\n models: { Staff: StaffModel, PermissionGroup: PermissionGroupModel },\n destroy,\n };\n}\n\n// ── Barrel re-exports ─────────────────────────────────────────────────────────\n\nexport * from './constants/index.js';\nexport * from './errors/index.js';\nexport * from './schemas/index.js';\nexport * from './services/index.js';\nexport * from './validation/index.js';\nexport * from './middleware/auth.middleware.js';\nexport * from './utils/error-handler.js';\nexport { createRoutes } from './routes/index.js';\nexport type { StaffEngineConfig, ResolvedOptions } from '@astralibx/staff-types';\nexport { DEFAULT_OPTIONS } from '@astralibx/staff-types';\n"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -122,7 +122,7 @@ declare class AuthService {
|
|
|
122
122
|
private allowSelfPasswordChange;
|
|
123
123
|
constructor(deps: AuthServiceDeps);
|
|
124
124
|
private get tenantFilter();
|
|
125
|
-
|
|
125
|
+
generateToken(staffId: string, role: string): string;
|
|
126
126
|
setupOwner(data: {
|
|
127
127
|
name: string;
|
|
128
128
|
email: string;
|
|
@@ -141,6 +141,8 @@ declare class AuthService {
|
|
|
141
141
|
|
|
142
142
|
interface StaffUser {
|
|
143
143
|
staffId: string;
|
|
144
|
+
name: string;
|
|
145
|
+
email: string;
|
|
144
146
|
role: string;
|
|
145
147
|
permissions: string[];
|
|
146
148
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -122,7 +122,7 @@ declare class AuthService {
|
|
|
122
122
|
private allowSelfPasswordChange;
|
|
123
123
|
constructor(deps: AuthServiceDeps);
|
|
124
124
|
private get tenantFilter();
|
|
125
|
-
|
|
125
|
+
generateToken(staffId: string, role: string): string;
|
|
126
126
|
setupOwner(data: {
|
|
127
127
|
name: string;
|
|
128
128
|
email: string;
|
|
@@ -141,6 +141,8 @@ declare class AuthService {
|
|
|
141
141
|
|
|
142
142
|
interface StaffUser {
|
|
143
143
|
staffId: string;
|
|
144
|
+
name: string;
|
|
145
|
+
email: string;
|
|
144
146
|
role: string;
|
|
145
147
|
permissions: string[];
|
|
146
148
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -694,11 +694,11 @@ function createAuthMiddleware(jwtSecret, permissionCache, StaffModel, logger, te
|
|
|
694
694
|
if (!payload.staffId || !payload.role) return null;
|
|
695
695
|
const filter = { _id: payload.staffId };
|
|
696
696
|
if (tenantId) filter.tenantId = tenantId;
|
|
697
|
-
const staff = await StaffModel.findOne(filter).select("status role").lean();
|
|
697
|
+
const staff = await StaffModel.findOne(filter).select("name email status role").lean();
|
|
698
698
|
if (!staff) return null;
|
|
699
699
|
if (staff.status !== STAFF_STATUS.Active) return null;
|
|
700
700
|
const permissions = await permissionCache.get(payload.staffId);
|
|
701
|
-
return { staffId: payload.staffId, role: staff.role, permissions };
|
|
701
|
+
return { staffId: payload.staffId, name: staff.name, email: staff.email, role: staff.role, permissions };
|
|
702
702
|
} catch {
|
|
703
703
|
return null;
|
|
704
704
|
}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/schemas/staff.schema.ts","../src/schemas/permission-group.schema.ts","../src/services/rate-limiter.service.ts","../src/services/permission-cache.service.ts","../src/constants/index.ts","../src/errors/index.ts","../src/services/permission.service.ts","../src/validation/permissions.ts","../src/validation/config.schema.ts","../src/services/staff.service.ts","../src/services/auth.service.ts","../src/middleware/auth.middleware.ts","../src/utils/error-handler.ts","../src/routes/auth.routes.ts","../src/routes/staff.routes.ts","../src/routes/permission-group.routes.ts","../src/routes/index.ts","../src/index.ts"],"names":["Schema","STAFF_STATUS","STAFF_ROLE","jwt","Router"],"mappings":"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","file":"index.mjs","sourcesContent":["import { Schema, type Connection, type Model, type Document, type Types } from 'mongoose';\nimport { STAFF_ROLE_VALUES, STAFF_STATUS_VALUES, STAFF_STATUS } from '@astralibx/staff-types';\nimport type { IStaff } from '@astralibx/staff-types';\n\nexport interface IStaffDocument extends Omit<IStaff, '_id'>, Document {\n _id: Types.ObjectId;\n}\n\nexport function createStaffModel(connection: Connection, prefix?: string): Model<IStaffDocument> {\n const schema = new Schema<IStaffDocument>(\n {\n name: { type: String, required: true, trim: true },\n email: { type: String, required: true, trim: true, lowercase: true },\n password: { type: String, required: true, select: false },\n role: { type: String, enum: STAFF_ROLE_VALUES, default: 'staff' },\n status: { type: String, enum: STAFF_STATUS_VALUES, default: STAFF_STATUS.Pending },\n permissions: { type: [String], default: [] },\n externalUserId: { type: String, sparse: true },\n lastLoginAt: { type: Date },\n lastLoginIp: { type: String },\n metadata: { type: Schema.Types.Mixed },\n tenantId: { type: String, sparse: true },\n },\n { timestamps: true },\n );\n\n schema.index({ email: 1, tenantId: 1 }, { unique: true });\n schema.index({ status: 1 });\n schema.index({ role: 1 });\n\n const collectionName = prefix ? `${prefix}_staff` : 'staff';\n return connection.model<IStaffDocument>('Staff', schema, collectionName);\n}\n","import { Schema, type Connection, type Model, type Document, type Types } from 'mongoose';\nimport { PERMISSION_TYPE_VALUES } from '@astralibx/staff-types';\nimport type { IPermissionGroup } from '@astralibx/staff-types';\n\nexport interface IPermissionGroupDocument extends Omit<IPermissionGroup, '_id'>, Document {\n _id: Types.ObjectId;\n}\n\nconst permissionEntrySchema = new Schema(\n {\n key: { type: String, required: true },\n label: { type: String, required: true },\n type: { type: String, enum: PERMISSION_TYPE_VALUES, required: true },\n },\n { _id: false },\n);\n\nexport function createPermissionGroupModel(\n connection: Connection,\n prefix?: string,\n): Model<IPermissionGroupDocument> {\n const schema = new Schema<IPermissionGroupDocument>(\n {\n groupId: { type: String, required: true },\n label: { type: String, required: true, trim: true },\n permissions: { type: [permissionEntrySchema], default: [] },\n sortOrder: { type: Number, default: 0 },\n tenantId: { type: String, index: true, sparse: true },\n },\n { timestamps: true },\n );\n\n schema.index({ groupId: 1, tenantId: 1 }, { unique: true });\n schema.index({ sortOrder: 1 });\n\n const collectionName = prefix ? `${prefix}_permission_groups` : 'permission_groups';\n return connection.model<IPermissionGroupDocument>('PermissionGroup', schema, collectionName);\n}\n","import type { LogAdapter } from '@astralibx/staff-types';\n\ninterface RateLimitEntry {\n count: number;\n expiresAt: number;\n}\n\nexport class RateLimiterService {\n private memoryStore = new Map<string, RateLimitEntry>();\n\n constructor(\n private windowMs: number,\n private maxAttempts: number,\n private redis: unknown | null,\n private keyPrefix: string,\n private logger: LogAdapter,\n ) {}\n\n async checkLimit(key: string): Promise<{ allowed: boolean; remaining: number; retryAfterMs?: number }> {\n if (this.redis) {\n return this.checkLimitRedis(key);\n }\n return this.checkLimitMemory(key);\n }\n\n async recordAttempt(key: string): Promise<void> {\n if (this.redis) {\n return this.recordAttemptRedis(key);\n }\n this.recordAttemptMemory(key);\n }\n\n async reset(key: string): Promise<void> {\n if (this.redis) {\n await (this.redis as any).del(`${this.keyPrefix}rate:${key}`);\n return;\n }\n this.memoryStore.delete(key);\n }\n\n private checkLimitMemory(key: string): { allowed: boolean; remaining: number; retryAfterMs?: number } {\n const entry = this.memoryStore.get(key);\n if (!entry || Date.now() > entry.expiresAt) {\n return { allowed: true, remaining: this.maxAttempts };\n }\n if (entry.count >= this.maxAttempts) {\n return { allowed: false, remaining: 0, retryAfterMs: entry.expiresAt - Date.now() };\n }\n return { allowed: true, remaining: this.maxAttempts - entry.count };\n }\n\n private recordAttemptMemory(key: string): void {\n const entry = this.memoryStore.get(key);\n if (!entry || Date.now() > entry.expiresAt) {\n this.memoryStore.set(key, { count: 1, expiresAt: Date.now() + this.windowMs });\n } else {\n entry.count++;\n }\n }\n\n private async checkLimitRedis(key: string): Promise<{ allowed: boolean; remaining: number; retryAfterMs?: number }> {\n const redisKey = `${this.keyPrefix}rate:${key}`;\n const redis = this.redis as any;\n const count = await redis.get(redisKey);\n const current = count ? parseInt(count, 10) : 0;\n if (current >= this.maxAttempts) {\n const ttl = await redis.pttl(redisKey);\n return { allowed: false, remaining: 0, retryAfterMs: ttl > 0 ? ttl : this.windowMs };\n }\n return { allowed: true, remaining: this.maxAttempts - current };\n }\n\n private async recordAttemptRedis(key: string): Promise<void> {\n const redisKey = `${this.keyPrefix}rate:${key}`;\n const redis = this.redis as any;\n const count = await redis.incr(redisKey);\n if (count === 1) {\n await redis.pexpire(redisKey, this.windowMs);\n }\n }\n}\n","import type { Model } from 'mongoose';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport type { IStaffDocument } from '../schemas/staff.schema.js';\n\nexport class PermissionCacheService {\n private memoryCache = new Map<string, { permissions: string[]; expiresAt: number }>();\n\n constructor(\n private StaffModel: Model<IStaffDocument>,\n private ttlMs: number,\n private redis: unknown | null,\n private keyPrefix: string,\n private logger: LogAdapter,\n private tenantId?: string,\n ) {}\n\n async get(staffId: string): Promise<string[]> {\n if (this.redis) {\n return this.getRedis(staffId);\n }\n return this.getMemory(staffId);\n }\n\n async invalidate(staffId: string): Promise<void> {\n if (this.redis) {\n await (this.redis as any).del(`${this.keyPrefix}perms:${staffId}`);\n return;\n }\n this.memoryCache.delete(staffId);\n }\n\n async invalidateAll(): Promise<void> {\n if (this.redis) {\n const redis = this.redis as any;\n const keys = await redis.keys(`${this.keyPrefix}perms:*`);\n if (keys.length > 0) {\n await redis.del(...keys);\n }\n return;\n }\n this.memoryCache.clear();\n }\n\n private async getMemory(staffId: string): Promise<string[]> {\n const cached = this.memoryCache.get(staffId);\n if (cached && Date.now() < cached.expiresAt) {\n return cached.permissions;\n }\n const permissions = await this.fetchFromDb(staffId);\n this.memoryCache.set(staffId, { permissions, expiresAt: Date.now() + this.ttlMs });\n return permissions;\n }\n\n private async getRedis(staffId: string): Promise<string[]> {\n const redisKey = `${this.keyPrefix}perms:${staffId}`;\n const redis = this.redis as any;\n const cached = await redis.get(redisKey);\n if (cached) {\n return JSON.parse(cached);\n }\n const permissions = await this.fetchFromDb(staffId);\n await redis.set(redisKey, JSON.stringify(permissions), 'PX', this.ttlMs);\n return permissions;\n }\n\n private async fetchFromDb(staffId: string): Promise<string[]> {\n const filter: Record<string, unknown> = { _id: staffId };\n if (this.tenantId) filter.tenantId = this.tenantId;\n const staff = await this.StaffModel.findOne(filter).select('permissions').lean();\n return staff?.permissions ?? [];\n }\n}\n","export const ERROR_CODE = {\n // Auth\n InvalidCredentials: 'STAFF_INVALID_CREDENTIALS',\n AccountInactive: 'STAFF_ACCOUNT_INACTIVE',\n AccountPending: 'STAFF_ACCOUNT_PENDING',\n RateLimited: 'STAFF_RATE_LIMITED',\n TokenExpired: 'STAFF_TOKEN_EXPIRED',\n TokenInvalid: 'STAFF_TOKEN_INVALID',\n InsufficientPermissions: 'STAFF_INSUFFICIENT_PERMISSIONS',\n OwnerOnly: 'STAFF_OWNER_ONLY',\n\n // CRUD\n StaffNotFound: 'STAFF_NOT_FOUND',\n EmailExists: 'STAFF_EMAIL_EXISTS',\n SetupAlreadyComplete: 'STAFF_SETUP_ALREADY_COMPLETE',\n LastOwnerGuard: 'STAFF_LAST_OWNER_GUARD',\n InvalidPermissions: 'STAFF_INVALID_PERMISSIONS',\n\n // Permission Groups\n GroupNotFound: 'STAFF_GROUP_NOT_FOUND',\n GroupIdExists: 'STAFF_GROUP_ID_EXISTS',\n\n // Config\n InvalidConfig: 'STAFF_INVALID_CONFIG',\n} as const;\n\nexport type ErrorCode = (typeof ERROR_CODE)[keyof typeof ERROR_CODE];\n\nexport const ERROR_MESSAGE = {\n InvalidCredentials: 'Invalid email or password',\n AccountInactive: 'Account is deactivated',\n AccountPending: 'Account is pending activation',\n RateLimited: 'Too many login attempts. Please try again later.',\n TokenExpired: 'Token has expired',\n TokenInvalid: 'Invalid token',\n InsufficientPermissions: 'Insufficient permissions',\n OwnerOnly: 'This action requires owner privileges',\n StaffNotFound: 'Staff member not found',\n EmailExists: 'A staff member with this email already exists',\n SetupAlreadyComplete: 'Initial setup has already been completed',\n LastOwnerGuard: 'Cannot deactivate the last active owner',\n InvalidPermissions: 'Edit permissions require corresponding view permissions',\n GroupNotFound: 'Permission group not found',\n GroupIdExists: 'A permission group with this ID already exists',\n InvalidConfig: 'Invalid engine configuration',\n} as const;\n\nexport const DEFAULTS = {\n ListPageSize: 20,\n MaxListPageSize: 100,\n PermissionCacheTtlMs: 5 * 60 * 1000,\n} as const;\n\nexport const DEFAULT_AUTH = {\n staffTokenExpiry: '24h',\n ownerTokenExpiry: '30d',\n permissionCacheTtlMs: 5 * 60 * 1000,\n} as const;\n","import { AlxError } from '@astralibx/core';\nimport { ERROR_CODE, ERROR_MESSAGE } from '../constants/index.js';\n\nexport class AlxStaffError extends AlxError {\n constructor(\n message: string,\n code: string,\n public readonly context?: Record<string, unknown>,\n ) {\n super(message, code);\n this.name = 'AlxStaffError';\n }\n}\n\nexport class AuthenticationError extends AlxStaffError {\n constructor(code: string = ERROR_CODE.InvalidCredentials, message?: string) {\n super(message || ERROR_MESSAGE.InvalidCredentials, code);\n this.name = 'AuthenticationError';\n }\n}\n\nexport class AuthorizationError extends AlxStaffError {\n constructor(code: string = ERROR_CODE.InsufficientPermissions, message?: string) {\n super(message || ERROR_MESSAGE.InsufficientPermissions, code);\n this.name = 'AuthorizationError';\n }\n}\n\nexport class RateLimitError extends AlxStaffError {\n constructor(public readonly retryAfterMs: number) {\n super(ERROR_MESSAGE.RateLimited, ERROR_CODE.RateLimited, { retryAfterMs });\n this.name = 'RateLimitError';\n }\n}\n\nexport class TokenError extends AlxStaffError {\n constructor(code: string = ERROR_CODE.TokenInvalid, message?: string) {\n super(message || ERROR_MESSAGE.TokenInvalid, code);\n this.name = 'TokenError';\n }\n}\n\nexport class StaffNotFoundError extends AlxStaffError {\n constructor(public readonly staffId: string) {\n super(ERROR_MESSAGE.StaffNotFound, ERROR_CODE.StaffNotFound, { staffId });\n this.name = 'StaffNotFoundError';\n }\n}\n\nexport class DuplicateError extends AlxStaffError {\n constructor(code: string, message: string, context?: Record<string, unknown>) {\n super(message, code, context);\n this.name = 'DuplicateError';\n }\n}\n\nexport class SetupError extends AlxStaffError {\n constructor() {\n super(ERROR_MESSAGE.SetupAlreadyComplete, ERROR_CODE.SetupAlreadyComplete);\n this.name = 'SetupError';\n }\n}\n\nexport class LastOwnerError extends AlxStaffError {\n constructor(public readonly staffId: string) {\n super(ERROR_MESSAGE.LastOwnerGuard, ERROR_CODE.LastOwnerGuard, { staffId });\n this.name = 'LastOwnerError';\n }\n}\n\nexport class InvalidPermissionError extends AlxStaffError {\n constructor(public readonly missingViewKeys: string[]) {\n super(ERROR_MESSAGE.InvalidPermissions, ERROR_CODE.InvalidPermissions, { missingViewKeys });\n this.name = 'InvalidPermissionError';\n }\n}\n\nexport class GroupNotFoundError extends AlxStaffError {\n constructor(public readonly groupId: string) {\n super(ERROR_MESSAGE.GroupNotFound, ERROR_CODE.GroupNotFound, { groupId });\n this.name = 'GroupNotFoundError';\n }\n}\n\nexport class InvalidConfigError extends AlxStaffError {\n constructor(public readonly field: string, public readonly reason: string) {\n super(`Invalid config for \"${field}\": ${reason}`, ERROR_CODE.InvalidConfig, { field, reason });\n this.name = 'InvalidConfigError';\n }\n}\n","import type { Model } from 'mongoose';\nimport type { LogAdapter, IPermissionGroupCreateInput, IPermissionGroupUpdateInput } from '@astralibx/staff-types';\nimport type { IPermissionGroupDocument } from '../schemas/permission-group.schema.js';\nimport { DuplicateError, GroupNotFoundError } from '../errors/index.js';\nimport { ERROR_CODE, ERROR_MESSAGE } from '../constants/index.js';\nimport type { PermissionCacheService } from './permission-cache.service.js';\n\nexport class PermissionService {\n constructor(\n private PermissionGroup: Model<IPermissionGroupDocument>,\n private permissionCache: PermissionCacheService,\n private logger: LogAdapter,\n private tenantId?: string,\n ) {}\n\n private get tenantFilter(): Record<string, unknown> {\n return this.tenantId ? { tenantId: this.tenantId } : {};\n }\n\n async listGroups(): Promise<IPermissionGroupDocument[]> {\n return this.PermissionGroup.find(this.tenantFilter).sort({ sortOrder: 1 }).lean() as unknown as IPermissionGroupDocument[];\n }\n\n async createGroup(data: IPermissionGroupCreateInput): Promise<IPermissionGroupDocument> {\n const existing = await this.PermissionGroup.findOne({\n groupId: data.groupId,\n ...this.tenantFilter,\n });\n if (existing) {\n throw new DuplicateError(\n ERROR_CODE.GroupIdExists,\n ERROR_MESSAGE.GroupIdExists,\n { groupId: data.groupId },\n );\n }\n const group = await this.PermissionGroup.create({\n ...data,\n sortOrder: data.sortOrder ?? 0,\n ...this.tenantFilter,\n });\n this.logger.info('Permission group created', { groupId: data.groupId });\n return group.toObject();\n }\n\n async updateGroup(groupId: string, data: IPermissionGroupUpdateInput): Promise<IPermissionGroupDocument> {\n const group = await this.PermissionGroup.findOneAndUpdate(\n { groupId, ...this.tenantFilter },\n { $set: data },\n { new: true },\n ).lean();\n if (!group) {\n throw new GroupNotFoundError(groupId);\n }\n await this.permissionCache.invalidateAll();\n this.logger.info('Permission group updated', { groupId, fields: Object.keys(data) });\n return group as unknown as IPermissionGroupDocument;\n }\n\n async deleteGroup(groupId: string): Promise<void> {\n const result = await this.PermissionGroup.deleteOne({ groupId, ...this.tenantFilter });\n if (result.deletedCount === 0) {\n throw new GroupNotFoundError(groupId);\n }\n await this.permissionCache.invalidateAll();\n this.logger.info('Permission group deleted', { groupId });\n }\n\n async getAllPermissionKeys(): Promise<string[]> {\n const groups = await this.listGroups();\n return groups.flatMap(g => g.permissions.map(p => p.key));\n }\n}\n","import { PERMISSION_TYPE } from '@astralibx/staff-types';\nimport { InvalidPermissionError } from '../errors/index.js';\nimport type { IPermissionGroupDocument } from '../schemas/permission-group.schema.js';\n\n/**\n * Validates that for every edit-type permission, the corresponding view-type permission\n * is also present. Single-level cascade only.\n * Example: 'chat:edit' requires 'chat:view'\n */\nexport function validatePermissionPairs(\n permissions: string[],\n allGroups: IPermissionGroupDocument[],\n): void {\n const allEntries = allGroups.flatMap(g => g.permissions);\n const editKeys = allEntries\n .filter(e => e.type === PERMISSION_TYPE.Edit)\n .map(e => e.key);\n\n const permissionSet = new Set(permissions);\n const missingViewKeys: string[] = [];\n\n for (const editKey of editKeys) {\n if (!permissionSet.has(editKey)) continue;\n const prefix = editKey.substring(0, editKey.lastIndexOf(':'));\n const viewKey = `${prefix}:view`;\n const viewEntry = allEntries.find(e => e.key === viewKey && e.type === PERMISSION_TYPE.View);\n if (viewEntry && !permissionSet.has(viewKey)) {\n missingViewKeys.push(viewKey);\n }\n }\n\n if (missingViewKeys.length > 0) {\n throw new InvalidPermissionError(missingViewKeys);\n }\n}\n","import { z } from 'zod';\n\nexport const StaffEngineConfigSchema = z.object({\n db: z.object({\n connection: z.unknown().refine((v) => v !== undefined && v !== null, {\n message: 'db.connection is required',\n }),\n collectionPrefix: z.string().optional(),\n }),\n redis: z\n .object({\n connection: z.unknown(),\n keyPrefix: z.string().optional(),\n })\n .optional(),\n logger: z\n .object({\n info: z.function(),\n warn: z.function(),\n error: z.function(),\n })\n .optional(),\n tenantId: z.string().optional(),\n auth: z.object({\n jwtSecret: z.string().min(1),\n staffTokenExpiry: z.string().optional(),\n ownerTokenExpiry: z.string().optional(),\n permissionCacheTtlMs: z.number().int().positive().optional(),\n }),\n adapters: z.object({\n hashPassword: z.function(),\n comparePassword: z.function(),\n }),\n hooks: z\n .object({\n onStaffCreated: z.function().optional(),\n onLogin: z.function().optional(),\n onLoginFailed: z.function().optional(),\n onPermissionsChanged: z.function().optional(),\n onStatusChanged: z.function().optional(),\n onMetric: z.function().optional(),\n })\n .optional(),\n options: z\n .object({\n requireEmailUniqueness: z.boolean().optional(),\n allowSelfPasswordChange: z.boolean().optional(),\n rateLimiter: z\n .object({\n windowMs: z.number().int().positive().optional(),\n maxAttempts: z.number().int().positive().optional(),\n })\n .optional(),\n })\n .optional(),\n});\n","import type { Model } from 'mongoose';\nimport type {\n LogAdapter, StaffHooks, StaffAdapters, IStaffCreateInput,\n IStaffUpdateInput, IStaffListFilters, IPaginatedResult,\n} from '@astralibx/staff-types';\nimport { STAFF_ROLE, STAFF_STATUS } from '@astralibx/staff-types';\nimport type { IStaffDocument } from '../schemas/staff.schema.js';\nimport type { IPermissionGroupDocument } from '../schemas/permission-group.schema.js';\nimport type { PermissionCacheService } from './permission-cache.service.js';\nimport {\n DuplicateError, StaffNotFoundError,\n LastOwnerError,\n} from '../errors/index.js';\nimport { ERROR_CODE, ERROR_MESSAGE, DEFAULTS } from '../constants/index.js';\nimport { validatePermissionPairs } from '../validation/index.js';\n\nexport interface StaffServiceDeps {\n Staff: Model<IStaffDocument>;\n PermissionGroup: Model<IPermissionGroupDocument>;\n adapters: StaffAdapters;\n hooks: StaffHooks;\n permissionCache: PermissionCacheService;\n logger: LogAdapter;\n tenantId?: string;\n requireEmailUniqueness: boolean;\n}\n\nexport class StaffService {\n private Staff: Model<IStaffDocument>;\n private PermissionGroup: Model<IPermissionGroupDocument>;\n private adapters: StaffAdapters;\n private hooks: StaffHooks;\n private permissionCache: PermissionCacheService;\n private logger: LogAdapter;\n private tenantId?: string;\n private requireEmailUniqueness: boolean;\n\n constructor(deps: StaffServiceDeps) {\n this.Staff = deps.Staff;\n this.PermissionGroup = deps.PermissionGroup;\n this.adapters = deps.adapters;\n this.hooks = deps.hooks;\n this.permissionCache = deps.permissionCache;\n this.logger = deps.logger;\n this.tenantId = deps.tenantId;\n this.requireEmailUniqueness = deps.requireEmailUniqueness;\n }\n\n private get tenantFilter(): Record<string, unknown> {\n return this.tenantId ? { tenantId: this.tenantId } : {};\n }\n\n async create(data: IStaffCreateInput): Promise<IStaffDocument> {\n if (this.requireEmailUniqueness) {\n const existing = await this.Staff.findOne({\n email: data.email.toLowerCase().trim(),\n ...this.tenantFilter,\n });\n if (existing) {\n throw new DuplicateError(ERROR_CODE.EmailExists, ERROR_MESSAGE.EmailExists, { email: data.email });\n }\n }\n\n const hashedPassword = await this.adapters.hashPassword(data.password);\n const staff = await this.Staff.create({\n ...data,\n email: data.email.toLowerCase().trim(),\n password: hashedPassword,\n role: data.role ?? STAFF_ROLE.Staff,\n status: data.status ?? STAFF_STATUS.Pending,\n permissions: data.permissions ?? [],\n ...this.tenantFilter,\n });\n\n this.logger.info('Staff created', { staffId: staff._id.toString() });\n this.hooks.onStaffCreated?.(staff.toObject());\n return staff.toObject();\n }\n\n async list(filters: IStaffListFilters = {}): Promise<IPaginatedResult<IStaffDocument>> {\n const page = Math.max(1, filters.page ?? 1);\n const limit = Math.min(filters.limit ?? DEFAULTS.ListPageSize, DEFAULTS.MaxListPageSize);\n\n const query: Record<string, unknown> = { ...this.tenantFilter };\n if (filters.status) query.status = filters.status;\n if (filters.role) query.role = filters.role;\n\n const [data, total] = await Promise.all([\n this.Staff.find(query)\n .sort({ createdAt: -1 })\n .skip((page - 1) * limit)\n .limit(limit)\n .lean(),\n this.Staff.countDocuments(query),\n ]);\n\n return {\n data: data as unknown as IStaffDocument[],\n pagination: { page, limit, total, totalPages: Math.ceil(total / limit) },\n };\n }\n\n async getById(staffId: string): Promise<IStaffDocument> {\n const staff = await this.Staff.findOne({ _id: staffId, ...this.tenantFilter }).lean() as unknown as IStaffDocument | null;\n if (!staff) throw new StaffNotFoundError(staffId);\n return staff;\n }\n\n async update(staffId: string, data: IStaffUpdateInput): Promise<IStaffDocument> {\n const updateData: Record<string, unknown> = {};\n if (data.name !== undefined) updateData.name = data.name;\n if (data.email !== undefined) updateData.email = data.email.toLowerCase().trim();\n if (data.metadata !== undefined) updateData.metadata = data.metadata;\n\n if (data.email && this.requireEmailUniqueness) {\n const existing = await this.Staff.findOne({\n email: data.email.toLowerCase().trim(),\n _id: { $ne: staffId },\n ...this.tenantFilter,\n });\n if (existing) {\n throw new DuplicateError(ERROR_CODE.EmailExists, ERROR_MESSAGE.EmailExists, { email: data.email });\n }\n }\n\n const staff = await this.Staff.findOneAndUpdate(\n { _id: staffId, ...this.tenantFilter },\n { $set: updateData },\n { new: true },\n ).lean() as unknown as IStaffDocument | null;\n if (!staff) throw new StaffNotFoundError(staffId);\n\n this.logger.info('Staff updated', { staffId, fields: Object.keys(updateData) });\n return staff;\n }\n\n async updatePermissions(staffId: string, permissions: string[]): Promise<IStaffDocument> {\n const groups = await this.PermissionGroup.find(this.tenantFilter).lean() as unknown as IPermissionGroupDocument[];\n validatePermissionPairs(permissions, groups);\n\n const staff = await this.Staff.findOne({ _id: staffId, ...this.tenantFilter });\n if (!staff) throw new StaffNotFoundError(staffId);\n\n const oldPerms = [...staff.permissions];\n staff.permissions = permissions;\n await staff.save();\n\n await this.permissionCache.invalidate(staffId);\n this.hooks.onPermissionsChanged?.(staffId, oldPerms, permissions);\n this.logger.info('Staff permissions updated', { staffId, count: permissions.length });\n return staff.toObject();\n }\n\n async updateStatus(staffId: string, status: string): Promise<IStaffDocument> {\n const staff = await this.Staff.findOne({ _id: staffId, ...this.tenantFilter });\n if (!staff) throw new StaffNotFoundError(staffId);\n\n if (status === STAFF_STATUS.Inactive && staff.role === STAFF_ROLE.Owner) {\n const activeOwnerCount = await this.Staff.countDocuments({\n role: STAFF_ROLE.Owner,\n status: STAFF_STATUS.Active,\n ...this.tenantFilter,\n });\n if (activeOwnerCount <= 1) throw new LastOwnerError(staffId);\n }\n\n const oldStatus = staff.status;\n staff.status = status as any;\n await staff.save();\n\n await this.permissionCache.invalidate(staffId);\n this.hooks.onStatusChanged?.(staffId, oldStatus, status);\n this.logger.info('Staff status updated', { staffId, oldStatus, newStatus: status });\n return staff.toObject();\n }\n}\n","import jwt from 'jsonwebtoken';\nimport type { Model } from 'mongoose';\nimport type {\n LogAdapter, StaffHooks, StaffAdapters,\n} from '@astralibx/staff-types';\nimport { STAFF_ROLE, STAFF_STATUS } from '@astralibx/staff-types';\nimport type { IStaffDocument } from '../schemas/staff.schema.js';\nimport type { RateLimiterService } from './rate-limiter.service.js';\nimport {\n AuthenticationError, StaffNotFoundError,\n SetupError, RateLimitError,\n} from '../errors/index.js';\nimport { ERROR_CODE, ERROR_MESSAGE } from '../constants/index.js';\n\nexport interface AuthServiceDeps {\n Staff: Model<IStaffDocument>;\n adapters: StaffAdapters;\n hooks: StaffHooks;\n rateLimiter: RateLimiterService;\n logger: LogAdapter;\n tenantId?: string;\n jwtSecret: string;\n staffTokenExpiry: string;\n ownerTokenExpiry: string;\n allowSelfPasswordChange: boolean;\n}\n\nexport class AuthService {\n private Staff: Model<IStaffDocument>;\n private adapters: StaffAdapters;\n private hooks: StaffHooks;\n private rateLimiter: RateLimiterService;\n private logger: LogAdapter;\n private tenantId?: string;\n private jwtSecret: string;\n private staffTokenExpiry: string;\n private ownerTokenExpiry: string;\n private allowSelfPasswordChange: boolean;\n\n constructor(deps: AuthServiceDeps) {\n this.Staff = deps.Staff;\n this.adapters = deps.adapters;\n this.hooks = deps.hooks;\n this.rateLimiter = deps.rateLimiter;\n this.logger = deps.logger;\n this.tenantId = deps.tenantId;\n this.jwtSecret = deps.jwtSecret;\n this.staffTokenExpiry = deps.staffTokenExpiry;\n this.ownerTokenExpiry = deps.ownerTokenExpiry;\n this.allowSelfPasswordChange = deps.allowSelfPasswordChange;\n }\n\n private get tenantFilter(): Record<string, unknown> {\n return this.tenantId ? { tenantId: this.tenantId } : {};\n }\n\n private generateToken(staffId: string, role: string): string {\n const expiresIn = role === STAFF_ROLE.Owner ? this.ownerTokenExpiry : this.staffTokenExpiry;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return jwt.sign({ staffId, role }, this.jwtSecret, { expiresIn } as any);\n }\n\n async setupOwner(data: { name: string; email: string; password: string }): Promise<{ staff: IStaffDocument; token: string }> {\n // Race-safe: check count first, then create. If two requests race past the\n // count check, the unique index on {email, tenantId} will reject the second\n // create, which we catch and convert to SetupError.\n const count = await this.Staff.countDocuments(this.tenantFilter);\n if (count > 0) throw new SetupError();\n\n const hashedPassword = await this.adapters.hashPassword(data.password);\n let staff: IStaffDocument;\n try {\n const doc = await this.Staff.create({\n name: data.name,\n email: data.email.toLowerCase().trim(),\n password: hashedPassword,\n role: STAFF_ROLE.Owner,\n status: STAFF_STATUS.Active,\n permissions: [],\n ...this.tenantFilter,\n });\n staff = doc.toObject() as unknown as IStaffDocument;\n } catch (err: unknown) {\n // Race condition: another request created a staff member between our count and create\n if (err && typeof err === 'object' && 'code' in err && (err as any).code === 11000) {\n throw new SetupError();\n }\n throw err;\n }\n const token = this.generateToken(staff._id.toString(), STAFF_ROLE.Owner);\n this.logger.info('Owner setup complete', { staffId: staff._id.toString() });\n this.hooks.onStaffCreated?.(staff);\n this.hooks.onMetric?.({ name: 'staff_setup_complete', value: 1 });\n return { staff, token };\n }\n\n async login(email: string, password: string, ip?: string): Promise<{ staff: IStaffDocument; token: string }> {\n if (ip) {\n const limit = await this.rateLimiter.checkLimit(ip);\n if (!limit.allowed) {\n this.hooks.onLoginFailed?.(email, ip);\n throw new RateLimitError(limit.retryAfterMs!);\n }\n }\n\n const staff = await this.Staff.findOne({\n email: email.toLowerCase().trim(),\n ...this.tenantFilter,\n }).select('+password');\n\n if (!staff) {\n if (ip) await this.rateLimiter.recordAttempt(ip);\n this.hooks.onLoginFailed?.(email, ip);\n throw new AuthenticationError(ERROR_CODE.InvalidCredentials);\n }\n\n const valid = await this.adapters.comparePassword(password, staff.password);\n if (!valid) {\n if (ip) await this.rateLimiter.recordAttempt(ip);\n this.hooks.onLoginFailed?.(email, ip);\n throw new AuthenticationError(ERROR_CODE.InvalidCredentials);\n }\n\n if (staff.status === STAFF_STATUS.Inactive) {\n throw new AuthenticationError(ERROR_CODE.AccountInactive, ERROR_MESSAGE.AccountInactive);\n }\n if (staff.status === STAFF_STATUS.Pending) {\n throw new AuthenticationError(ERROR_CODE.AccountPending, ERROR_MESSAGE.AccountPending);\n }\n\n staff.lastLoginAt = new Date();\n if (ip) staff.lastLoginIp = ip;\n await staff.save();\n\n if (ip) await this.rateLimiter.reset(ip);\n const token = this.generateToken(staff._id.toString(), staff.role);\n this.hooks.onLogin?.(staff.toObject(), ip);\n this.hooks.onMetric?.({ name: 'staff_login', value: 1, labels: { role: staff.role } });\n this.logger.info('Staff login', { staffId: staff._id.toString() });\n\n const staffObj = staff.toObject();\n delete (staffObj as any).password;\n return { staff: staffObj, token };\n }\n\n async resetPassword(staffId: string, newPassword: string): Promise<void> {\n const staff = await this.Staff.findOne({ _id: staffId, ...this.tenantFilter });\n if (!staff) throw new StaffNotFoundError(staffId);\n\n staff.password = await this.adapters.hashPassword(newPassword);\n await staff.save();\n this.logger.info('Staff password reset', { staffId });\n }\n\n async changeOwnPassword(staffId: string, oldPassword: string, newPassword: string): Promise<void> {\n if (!this.allowSelfPasswordChange) {\n throw new AuthenticationError(ERROR_CODE.InsufficientPermissions, 'Self password change is disabled');\n }\n\n const staff = await this.Staff.findOne({ _id: staffId, ...this.tenantFilter }).select('+password');\n if (!staff) throw new StaffNotFoundError(staffId);\n\n const valid = await this.adapters.comparePassword(oldPassword, staff.password);\n if (!valid) throw new AuthenticationError(ERROR_CODE.InvalidCredentials, 'Current password is incorrect');\n\n staff.password = await this.adapters.hashPassword(newPassword);\n await staff.save();\n this.logger.info('Staff changed own password', { staffId });\n }\n}\n","import jwt from 'jsonwebtoken';\nimport type { Request, Response, NextFunction, RequestHandler } from 'express';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport { STAFF_ROLE, STAFF_STATUS } from '@astralibx/staff-types';\nimport type { PermissionCacheService } from '../services/permission-cache.service.js';\nimport type { IStaffDocument } from '../schemas/staff.schema.js';\nimport type { Model } from 'mongoose';\nimport { TokenError, AuthorizationError } from '../errors/index.js';\nimport { ERROR_CODE, ERROR_MESSAGE } from '../constants/index.js';\n\nexport interface StaffUser {\n staffId: string;\n role: string;\n permissions: string[];\n}\n\nexport interface AuthenticatedRequest extends Request {\n user: StaffUser;\n}\n\nexport interface AuthMiddleware {\n verifyToken: RequestHandler;\n resolveStaff: (token: string) => Promise<StaffUser | null>;\n requirePermission: (...keys: string[]) => RequestHandler;\n ownerOnly: RequestHandler;\n requireRole: (...roles: string[]) => RequestHandler;\n}\n\nexport function createAuthMiddleware(\n jwtSecret: string,\n permissionCache: PermissionCacheService,\n StaffModel: Model<IStaffDocument>,\n logger: LogAdapter,\n tenantId?: string,\n): AuthMiddleware {\n\n async function resolveStaffFromToken(token: string): Promise<StaffUser | null> {\n try {\n const payload = jwt.verify(token, jwtSecret) as { staffId: string; role: string };\n if (!payload.staffId || !payload.role) return null;\n\n // Check staff status\n const filter: Record<string, unknown> = { _id: payload.staffId };\n if (tenantId) filter.tenantId = tenantId;\n const staff = await StaffModel.findOne(filter).select('status role').lean();\n if (!staff) return null;\n if (staff.status !== STAFF_STATUS.Active) return null;\n\n const permissions = await permissionCache.get(payload.staffId);\n return { staffId: payload.staffId, role: staff.role, permissions };\n } catch {\n return null;\n }\n }\n\n const verifyToken: RequestHandler = async (req: Request, res: Response, next: NextFunction) => {\n const authHeader = req.headers.authorization;\n if (!authHeader?.startsWith('Bearer ')) {\n res.status(401).json({ success: false, error: ERROR_MESSAGE.TokenInvalid, code: ERROR_CODE.TokenInvalid });\n return;\n }\n\n const token = authHeader.slice(7);\n\n // Distinguish expired vs invalid tokens before full resolution\n try {\n jwt.verify(token, jwtSecret);\n } catch (err: unknown) {\n if (err instanceof jwt.TokenExpiredError) {\n res.status(401).json({ success: false, error: ERROR_MESSAGE.TokenExpired, code: ERROR_CODE.TokenExpired });\n return;\n }\n res.status(401).json({ success: false, error: ERROR_MESSAGE.TokenInvalid, code: ERROR_CODE.TokenInvalid });\n return;\n }\n\n const user = await resolveStaffFromToken(token);\n if (!user) {\n res.status(401).json({ success: false, error: ERROR_MESSAGE.TokenInvalid, code: ERROR_CODE.TokenInvalid });\n return;\n }\n\n (req as AuthenticatedRequest).user = user;\n next();\n };\n\n function requirePermission(...keys: string[]): RequestHandler {\n return (req: Request, res: Response, next: NextFunction) => {\n const user = (req as AuthenticatedRequest).user;\n if (!user) {\n res.status(401).json({ success: false, error: ERROR_MESSAGE.TokenInvalid, code: ERROR_CODE.TokenInvalid });\n return;\n }\n\n // Owner bypasses permission checks\n if (user.role === STAFF_ROLE.Owner) {\n next();\n return;\n }\n\n const permSet = new Set(user.permissions);\n const missing: string[] = [];\n\n for (const key of keys) {\n if (!permSet.has(key)) {\n missing.push(key);\n continue;\n }\n // Single-level edit→view cascade\n if (key.endsWith(':edit')) {\n const prefix = key.substring(0, key.lastIndexOf(':'));\n const viewKey = `${prefix}:view`;\n if (!permSet.has(viewKey)) {\n missing.push(viewKey);\n }\n }\n }\n\n if (missing.length > 0) {\n res.status(403).json({\n success: false,\n error: ERROR_MESSAGE.InsufficientPermissions,\n code: ERROR_CODE.InsufficientPermissions,\n missing,\n });\n return;\n }\n\n next();\n };\n }\n\n const ownerOnly: RequestHandler = (req: Request, res: Response, next: NextFunction) => {\n const user = (req as AuthenticatedRequest).user;\n if (!user || user.role !== STAFF_ROLE.Owner) {\n res.status(403).json({ success: false, error: ERROR_MESSAGE.OwnerOnly, code: ERROR_CODE.OwnerOnly });\n return;\n }\n next();\n };\n\n function requireRole(...roles: string[]): RequestHandler {\n return (req: Request, res: Response, next: NextFunction) => {\n const user = (req as AuthenticatedRequest).user;\n if (!user || !roles.includes(user.role)) {\n res.status(403).json({ success: false, error: ERROR_MESSAGE.InsufficientPermissions, code: ERROR_CODE.InsufficientPermissions });\n return;\n }\n next();\n };\n }\n\n return {\n verifyToken,\n resolveStaff: resolveStaffFromToken,\n requirePermission,\n ownerOnly,\n requireRole,\n };\n}\n","import type { Response } from 'express';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport { sendSuccess, sendError } from '@astralibx/core';\nimport {\n AlxStaffError, AuthenticationError, AuthorizationError,\n RateLimitError, TokenError, StaffNotFoundError, DuplicateError,\n SetupError, LastOwnerError, InvalidPermissionError, GroupNotFoundError,\n} from '../errors/index.js';\n\nexport { sendSuccess };\n\nfunction sendStaffError(res: Response, error: AlxStaffError, status: number): void {\n res.status(status).json({ success: false, error: error.message, code: error.code });\n}\n\nexport function handleStaffError(res: Response, error: unknown, logger: LogAdapter): void {\n if (error instanceof RateLimitError) {\n res.set('Retry-After', String(Math.ceil(error.retryAfterMs / 1000)));\n sendStaffError(res, error, 429);\n } else if (error instanceof AuthenticationError || error instanceof TokenError) {\n sendStaffError(res, error, 401);\n } else if (error instanceof AuthorizationError || error instanceof SetupError) {\n sendStaffError(res, error, 403);\n } else if (error instanceof StaffNotFoundError || error instanceof GroupNotFoundError) {\n sendStaffError(res, error, 404);\n } else if (error instanceof DuplicateError) {\n sendStaffError(res, error, 409);\n } else if (error instanceof LastOwnerError || error instanceof InvalidPermissionError) {\n sendStaffError(res, error, 400);\n } else if (error instanceof AlxStaffError) {\n sendStaffError(res, error, 400);\n } else {\n const message = error instanceof Error ? error.message : 'Unknown error';\n logger.error('Unexpected error', { error: message });\n sendError(res, message, 500);\n }\n}\n","import { Router } from 'express';\nimport type { Request, Response } from 'express';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport type { StaffService } from '../services/staff.service.js';\nimport type { AuthService } from '../services/auth.service.js';\nimport type { AuthMiddleware, AuthenticatedRequest } from '../middleware/auth.middleware.js';\nimport { sendSuccess, handleStaffError } from '../utils/error-handler.js';\n\nexport function createAuthRoutes(\n staffService: StaffService,\n authService: AuthService,\n auth: AuthMiddleware,\n logger: LogAdapter,\n allowSelfPasswordChange: boolean,\n): Router {\n const router = Router();\n\n // POST /setup — public, creates initial owner account\n router.post('/setup', async (req: Request, res: Response) => {\n try {\n const result = await authService.setupOwner(req.body);\n sendSuccess(res, result, 201);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // POST /login — public, returns staff + token\n router.post('/login', async (req: Request, res: Response) => {\n try {\n const { email, password } = req.body as { email: string; password: string };\n const ip = req.ip || req.socket.remoteAddress || '';\n const result = await authService.login(email, password, ip);\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // GET /me — authenticated, returns current staff profile + permissions\n router.get('/me', auth.verifyToken, async (req: Request, res: Response) => {\n try {\n const user = (req as AuthenticatedRequest).user;\n const staff = await staffService.getById(user.staffId);\n sendSuccess(res, { staff, permissions: user.permissions });\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /me/password — only mounted if allowSelfPasswordChange is true\n if (allowSelfPasswordChange) {\n router.put('/me/password', auth.verifyToken, async (req: Request, res: Response) => {\n try {\n const user = (req as AuthenticatedRequest).user;\n const { oldPassword, newPassword } = req.body as { oldPassword: string; newPassword: string };\n await authService.changeOwnPassword(user.staffId, oldPassword, newPassword);\n sendSuccess(res, { message: 'Password changed successfully' });\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n }\n\n return router;\n}\n","import { Router } from 'express';\nimport type { Request, Response } from 'express';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport type { StaffService } from '../services/staff.service.js';\nimport type { AuthService } from '../services/auth.service.js';\nimport { sendSuccess, handleStaffError } from '../utils/error-handler.js';\n\nexport function createStaffRoutes(\n staffService: StaffService,\n logger: LogAdapter,\n authService?: AuthService,\n): Router {\n const router = Router();\n\n // GET / — list staff\n router.get('/', async (req: Request, res: Response) => {\n try {\n const query = req.query as Record<string, string | undefined>;\n const filters: Record<string, unknown> = {};\n if (query['status']) filters['status'] = query['status'];\n if (query['role']) filters['role'] = query['role'];\n if (query['page']) filters['page'] = parseInt(query['page']!, 10);\n if (query['limit']) filters['limit'] = parseInt(query['limit']!, 10);\n const result = await staffService.list(filters as Parameters<typeof staffService.list>[0]);\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // POST / — create staff member\n router.post('/', async (req: Request, res: Response) => {\n try {\n const result = await staffService.create(req.body);\n sendSuccess(res, result, 201);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /:staffId — update staff member\n router.put('/:staffId', async (req: Request, res: Response) => {\n try {\n const result = await staffService.update(req.params['staffId']!, req.body);\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /:staffId/permissions — update staff permissions\n router.put('/:staffId/permissions', async (req: Request, res: Response) => {\n try {\n const result = await staffService.updatePermissions(\n req.params['staffId']!,\n req.body.permissions,\n );\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /:staffId/status — update staff status\n router.put('/:staffId/status', async (req: Request, res: Response) => {\n try {\n const result = await staffService.updateStatus(\n req.params['staffId']!,\n req.body.status,\n );\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /:staffId/password — reset staff password (owner action)\n router.put('/:staffId/password', async (req: Request, res: Response) => {\n try {\n if (!authService) {\n throw new Error('AuthService not available');\n }\n await authService.resetPassword(req.params['staffId']!, req.body.password);\n sendSuccess(res, { message: 'Password reset successfully' });\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n return router;\n}\n","import { Router } from 'express';\nimport type { Request, Response } from 'express';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport type { PermissionService } from '../services/permission.service.js';\nimport type { AuthMiddleware } from '../middleware/auth.middleware.js';\nimport { sendSuccess, handleStaffError } from '../utils/error-handler.js';\n\nexport function createPermissionGroupRoutes(\n permissionService: PermissionService,\n auth: AuthMiddleware,\n logger: LogAdapter,\n): Router {\n const router = Router();\n\n // GET / — authenticated, list all permission groups\n router.get('/', auth.verifyToken, async (req: Request, res: Response) => {\n try {\n const result = await permissionService.listGroups();\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // POST / — owner only, create permission group\n router.post('/', auth.verifyToken, auth.ownerOnly, async (req: Request, res: Response) => {\n try {\n const result = await permissionService.createGroup(req.body);\n sendSuccess(res, result, 201);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /:groupId — owner only, update permission group\n router.put('/:groupId', auth.verifyToken, auth.ownerOnly, async (req: Request, res: Response) => {\n try {\n const result = await permissionService.updateGroup(req.params['groupId']!, req.body);\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // DELETE /:groupId — owner only, delete permission group\n router.delete('/:groupId', auth.verifyToken, auth.ownerOnly, async (req: Request, res: Response) => {\n try {\n await permissionService.deleteGroup(req.params['groupId']!);\n sendSuccess(res, { message: 'Group deleted successfully' });\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n return router;\n}\n","import { Router } from 'express';\nimport type { StaffService } from '../services/staff.service.js';\nimport type { AuthService } from '../services/auth.service.js';\nimport type { PermissionService } from '../services/permission.service.js';\nimport type { AuthMiddleware } from '../middleware/auth.middleware.js';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport { createAuthRoutes } from './auth.routes.js';\nimport { createStaffRoutes } from './staff.routes.js';\nimport { createPermissionGroupRoutes } from './permission-group.routes.js';\n\nexport interface RouteServices {\n staff: StaffService;\n auth: AuthService;\n permissions: PermissionService;\n}\n\nexport function createRoutes(\n services: RouteServices,\n auth: AuthMiddleware,\n logger: LogAdapter,\n allowSelfPasswordChange: boolean,\n): Router {\n const router = Router();\n\n // Public + authenticated routes (setup, login, /me)\n router.use('/', createAuthRoutes(services.staff, services.auth, auth, logger, allowSelfPasswordChange));\n\n // Owner-only staff CRUD routes\n router.use('/', auth.verifyToken, auth.ownerOnly, createStaffRoutes(services.staff, logger, services.auth));\n\n // Permission group routes (GET is authenticated, CUD is owner-only)\n router.use('/permission-groups', createPermissionGroupRoutes(services.permissions, auth, logger));\n\n return router;\n}\n","import { noopLogger } from '@astralibx/core';\nimport type { Router } from 'express';\nimport type { Model } from 'mongoose';\nimport type { StaffEngineConfig, ResolvedOptions } from '@astralibx/staff-types';\nimport { DEFAULT_OPTIONS } from '@astralibx/staff-types';\nimport { createStaffModel, type IStaffDocument } from './schemas/staff.schema.js';\nimport { createPermissionGroupModel, type IPermissionGroupDocument } from './schemas/permission-group.schema.js';\nimport { RateLimiterService } from './services/rate-limiter.service.js';\nimport { PermissionCacheService } from './services/permission-cache.service.js';\nimport { PermissionService } from './services/permission.service.js';\nimport { StaffService } from './services/staff.service.js';\nimport { AuthService } from './services/auth.service.js';\nimport { createAuthMiddleware, type AuthMiddleware } from './middleware/auth.middleware.js';\nimport { createRoutes } from './routes/index.js';\nimport { DEFAULT_AUTH } from './constants/index.js';\nimport { InvalidConfigError } from './errors/index.js';\nimport { StaffEngineConfigSchema } from './validation/config.schema.js';\n\n// ── Return type ───────────────────────────────────────────────────────────────\n\nexport interface StaffEngine {\n routes: Router;\n auth: AuthMiddleware;\n staff: StaffService;\n authService: AuthService;\n permissions: PermissionService;\n models: {\n Staff: Model<IStaffDocument>;\n PermissionGroup: Model<IPermissionGroupDocument>;\n };\n destroy: () => Promise<void>;\n}\n\n// ── Factory ───────────────────────────────────────────────────────────────────\n\nexport function createStaffEngine(config: StaffEngineConfig): StaffEngine {\n // 1. Validate config with Zod\n const parseResult = StaffEngineConfigSchema.safeParse(config);\n if (!parseResult.success) {\n const issues = parseResult.error.issues\n .map((i) => `${i.path.join('.')}: ${i.message}`)\n .join(', ');\n throw new InvalidConfigError('config', issues);\n }\n\n // 2. Resolve options\n const resolvedOptions: ResolvedOptions = {\n requireEmailUniqueness:\n config.options?.requireEmailUniqueness ?? DEFAULT_OPTIONS.requireEmailUniqueness,\n allowSelfPasswordChange:\n config.options?.allowSelfPasswordChange ?? DEFAULT_OPTIONS.allowSelfPasswordChange,\n rateLimiter: {\n windowMs:\n config.options?.rateLimiter?.windowMs ?? DEFAULT_OPTIONS.rateLimiter.windowMs,\n maxAttempts:\n config.options?.rateLimiter?.maxAttempts ?? DEFAULT_OPTIONS.rateLimiter.maxAttempts,\n },\n };\n\n const resolvedAuth = {\n jwtSecret: config.auth.jwtSecret,\n staffTokenExpiry: config.auth.staffTokenExpiry ?? DEFAULT_AUTH.staffTokenExpiry,\n ownerTokenExpiry: config.auth.ownerTokenExpiry ?? DEFAULT_AUTH.ownerTokenExpiry,\n permissionCacheTtlMs: config.auth.permissionCacheTtlMs ?? DEFAULT_AUTH.permissionCacheTtlMs,\n };\n\n // 3. Set up logger\n const logger = config.logger ?? noopLogger;\n\n // 4. Register mongoose models\n const conn = config.db.connection as import('mongoose').Connection;\n const prefix = config.db.collectionPrefix;\n\n const StaffModel = createStaffModel(conn, prefix);\n const PermissionGroupModel = createPermissionGroupModel(conn, prefix);\n\n // 5. Create services (dependency order)\n const redis = config.redis?.connection ?? null;\n const keyPrefix = config.redis?.keyPrefix ?? 'staff:';\n\n const rateLimiter = new RateLimiterService(\n resolvedOptions.rateLimiter.windowMs,\n resolvedOptions.rateLimiter.maxAttempts,\n redis,\n keyPrefix,\n logger,\n );\n\n const permissionCache = new PermissionCacheService(\n StaffModel,\n resolvedAuth.permissionCacheTtlMs,\n redis,\n keyPrefix,\n logger,\n config.tenantId,\n );\n\n const permissionService = new PermissionService(\n PermissionGroupModel,\n permissionCache,\n logger,\n config.tenantId,\n );\n\n const staffService = new StaffService({\n Staff: StaffModel,\n PermissionGroup: PermissionGroupModel,\n adapters: config.adapters,\n hooks: config.hooks ?? {},\n permissionCache,\n logger,\n tenantId: config.tenantId,\n requireEmailUniqueness: resolvedOptions.requireEmailUniqueness,\n });\n\n const authService = new AuthService({\n Staff: StaffModel,\n adapters: config.adapters,\n hooks: config.hooks ?? {},\n rateLimiter,\n logger,\n tenantId: config.tenantId,\n jwtSecret: resolvedAuth.jwtSecret,\n staffTokenExpiry: resolvedAuth.staffTokenExpiry,\n ownerTokenExpiry: resolvedAuth.ownerTokenExpiry,\n allowSelfPasswordChange: resolvedOptions.allowSelfPasswordChange,\n });\n\n // 6. Create auth middleware\n const auth = createAuthMiddleware(\n resolvedAuth.jwtSecret,\n permissionCache,\n StaffModel,\n logger,\n config.tenantId,\n );\n\n // 7. Create routes\n const routes = createRoutes(\n { staff: staffService, auth: authService, permissions: permissionService },\n auth,\n logger,\n resolvedOptions.allowSelfPasswordChange,\n );\n\n // 8. Return engine object\n async function destroy(): Promise<void> {\n await permissionCache.invalidateAll();\n logger.info('StaffEngine destroyed');\n }\n\n return {\n routes,\n auth,\n staff: staffService,\n authService,\n permissions: permissionService,\n models: { Staff: StaffModel, PermissionGroup: PermissionGroupModel },\n destroy,\n };\n}\n\n// ── Barrel re-exports ─────────────────────────────────────────────────────────\n\nexport * from './constants/index.js';\nexport * from './errors/index.js';\nexport * from './schemas/index.js';\nexport * from './services/index.js';\nexport * from './validation/index.js';\nexport * from './middleware/auth.middleware.js';\nexport * from './utils/error-handler.js';\nexport { createRoutes } from './routes/index.js';\nexport type { StaffEngineConfig, ResolvedOptions } from '@astralibx/staff-types';\nexport { DEFAULT_OPTIONS } from '@astralibx/staff-types';\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/schemas/staff.schema.ts","../src/schemas/permission-group.schema.ts","../src/services/rate-limiter.service.ts","../src/services/permission-cache.service.ts","../src/constants/index.ts","../src/errors/index.ts","../src/services/permission.service.ts","../src/validation/permissions.ts","../src/validation/config.schema.ts","../src/services/staff.service.ts","../src/services/auth.service.ts","../src/middleware/auth.middleware.ts","../src/utils/error-handler.ts","../src/routes/auth.routes.ts","../src/routes/staff.routes.ts","../src/routes/permission-group.routes.ts","../src/routes/index.ts","../src/index.ts"],"names":["Schema","STAFF_STATUS","STAFF_ROLE","jwt","Router"],"mappings":"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","file":"index.mjs","sourcesContent":["import { Schema, type Connection, type Model, type Document, type Types } from 'mongoose';\nimport { STAFF_ROLE_VALUES, STAFF_STATUS_VALUES, STAFF_STATUS } from '@astralibx/staff-types';\nimport type { IStaff } from '@astralibx/staff-types';\n\nexport interface IStaffDocument extends Omit<IStaff, '_id'>, Document {\n _id: Types.ObjectId;\n}\n\nexport function createStaffModel(connection: Connection, prefix?: string): Model<IStaffDocument> {\n const schema = new Schema<IStaffDocument>(\n {\n name: { type: String, required: true, trim: true },\n email: { type: String, required: true, trim: true, lowercase: true },\n password: { type: String, required: true, select: false },\n role: { type: String, enum: STAFF_ROLE_VALUES, default: 'staff' },\n status: { type: String, enum: STAFF_STATUS_VALUES, default: STAFF_STATUS.Pending },\n permissions: { type: [String], default: [] },\n externalUserId: { type: String, sparse: true },\n lastLoginAt: { type: Date },\n lastLoginIp: { type: String },\n metadata: { type: Schema.Types.Mixed },\n tenantId: { type: String, sparse: true },\n },\n { timestamps: true },\n );\n\n schema.index({ email: 1, tenantId: 1 }, { unique: true });\n schema.index({ status: 1 });\n schema.index({ role: 1 });\n\n const collectionName = prefix ? `${prefix}_staff` : 'staff';\n return connection.model<IStaffDocument>('Staff', schema, collectionName);\n}\n","import { Schema, type Connection, type Model, type Document, type Types } from 'mongoose';\nimport { PERMISSION_TYPE_VALUES } from '@astralibx/staff-types';\nimport type { IPermissionGroup } from '@astralibx/staff-types';\n\nexport interface IPermissionGroupDocument extends Omit<IPermissionGroup, '_id'>, Document {\n _id: Types.ObjectId;\n}\n\nconst permissionEntrySchema = new Schema(\n {\n key: { type: String, required: true },\n label: { type: String, required: true },\n type: { type: String, enum: PERMISSION_TYPE_VALUES, required: true },\n },\n { _id: false },\n);\n\nexport function createPermissionGroupModel(\n connection: Connection,\n prefix?: string,\n): Model<IPermissionGroupDocument> {\n const schema = new Schema<IPermissionGroupDocument>(\n {\n groupId: { type: String, required: true },\n label: { type: String, required: true, trim: true },\n permissions: { type: [permissionEntrySchema], default: [] },\n sortOrder: { type: Number, default: 0 },\n tenantId: { type: String, index: true, sparse: true },\n },\n { timestamps: true },\n );\n\n schema.index({ groupId: 1, tenantId: 1 }, { unique: true });\n schema.index({ sortOrder: 1 });\n\n const collectionName = prefix ? `${prefix}_permission_groups` : 'permission_groups';\n return connection.model<IPermissionGroupDocument>('PermissionGroup', schema, collectionName);\n}\n","import type { LogAdapter } from '@astralibx/staff-types';\n\ninterface RateLimitEntry {\n count: number;\n expiresAt: number;\n}\n\nexport class RateLimiterService {\n private memoryStore = new Map<string, RateLimitEntry>();\n\n constructor(\n private windowMs: number,\n private maxAttempts: number,\n private redis: unknown | null,\n private keyPrefix: string,\n private logger: LogAdapter,\n ) {}\n\n async checkLimit(key: string): Promise<{ allowed: boolean; remaining: number; retryAfterMs?: number }> {\n if (this.redis) {\n return this.checkLimitRedis(key);\n }\n return this.checkLimitMemory(key);\n }\n\n async recordAttempt(key: string): Promise<void> {\n if (this.redis) {\n return this.recordAttemptRedis(key);\n }\n this.recordAttemptMemory(key);\n }\n\n async reset(key: string): Promise<void> {\n if (this.redis) {\n await (this.redis as any).del(`${this.keyPrefix}rate:${key}`);\n return;\n }\n this.memoryStore.delete(key);\n }\n\n private checkLimitMemory(key: string): { allowed: boolean; remaining: number; retryAfterMs?: number } {\n const entry = this.memoryStore.get(key);\n if (!entry || Date.now() > entry.expiresAt) {\n return { allowed: true, remaining: this.maxAttempts };\n }\n if (entry.count >= this.maxAttempts) {\n return { allowed: false, remaining: 0, retryAfterMs: entry.expiresAt - Date.now() };\n }\n return { allowed: true, remaining: this.maxAttempts - entry.count };\n }\n\n private recordAttemptMemory(key: string): void {\n const entry = this.memoryStore.get(key);\n if (!entry || Date.now() > entry.expiresAt) {\n this.memoryStore.set(key, { count: 1, expiresAt: Date.now() + this.windowMs });\n } else {\n entry.count++;\n }\n }\n\n private async checkLimitRedis(key: string): Promise<{ allowed: boolean; remaining: number; retryAfterMs?: number }> {\n const redisKey = `${this.keyPrefix}rate:${key}`;\n const redis = this.redis as any;\n const count = await redis.get(redisKey);\n const current = count ? parseInt(count, 10) : 0;\n if (current >= this.maxAttempts) {\n const ttl = await redis.pttl(redisKey);\n return { allowed: false, remaining: 0, retryAfterMs: ttl > 0 ? ttl : this.windowMs };\n }\n return { allowed: true, remaining: this.maxAttempts - current };\n }\n\n private async recordAttemptRedis(key: string): Promise<void> {\n const redisKey = `${this.keyPrefix}rate:${key}`;\n const redis = this.redis as any;\n const count = await redis.incr(redisKey);\n if (count === 1) {\n await redis.pexpire(redisKey, this.windowMs);\n }\n }\n}\n","import type { Model } from 'mongoose';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport type { IStaffDocument } from '../schemas/staff.schema.js';\n\nexport class PermissionCacheService {\n private memoryCache = new Map<string, { permissions: string[]; expiresAt: number }>();\n\n constructor(\n private StaffModel: Model<IStaffDocument>,\n private ttlMs: number,\n private redis: unknown | null,\n private keyPrefix: string,\n private logger: LogAdapter,\n private tenantId?: string,\n ) {}\n\n async get(staffId: string): Promise<string[]> {\n if (this.redis) {\n return this.getRedis(staffId);\n }\n return this.getMemory(staffId);\n }\n\n async invalidate(staffId: string): Promise<void> {\n if (this.redis) {\n await (this.redis as any).del(`${this.keyPrefix}perms:${staffId}`);\n return;\n }\n this.memoryCache.delete(staffId);\n }\n\n async invalidateAll(): Promise<void> {\n if (this.redis) {\n const redis = this.redis as any;\n const keys = await redis.keys(`${this.keyPrefix}perms:*`);\n if (keys.length > 0) {\n await redis.del(...keys);\n }\n return;\n }\n this.memoryCache.clear();\n }\n\n private async getMemory(staffId: string): Promise<string[]> {\n const cached = this.memoryCache.get(staffId);\n if (cached && Date.now() < cached.expiresAt) {\n return cached.permissions;\n }\n const permissions = await this.fetchFromDb(staffId);\n this.memoryCache.set(staffId, { permissions, expiresAt: Date.now() + this.ttlMs });\n return permissions;\n }\n\n private async getRedis(staffId: string): Promise<string[]> {\n const redisKey = `${this.keyPrefix}perms:${staffId}`;\n const redis = this.redis as any;\n const cached = await redis.get(redisKey);\n if (cached) {\n return JSON.parse(cached);\n }\n const permissions = await this.fetchFromDb(staffId);\n await redis.set(redisKey, JSON.stringify(permissions), 'PX', this.ttlMs);\n return permissions;\n }\n\n private async fetchFromDb(staffId: string): Promise<string[]> {\n const filter: Record<string, unknown> = { _id: staffId };\n if (this.tenantId) filter.tenantId = this.tenantId;\n const staff = await this.StaffModel.findOne(filter).select('permissions').lean();\n return staff?.permissions ?? [];\n }\n}\n","export const ERROR_CODE = {\n // Auth\n InvalidCredentials: 'STAFF_INVALID_CREDENTIALS',\n AccountInactive: 'STAFF_ACCOUNT_INACTIVE',\n AccountPending: 'STAFF_ACCOUNT_PENDING',\n RateLimited: 'STAFF_RATE_LIMITED',\n TokenExpired: 'STAFF_TOKEN_EXPIRED',\n TokenInvalid: 'STAFF_TOKEN_INVALID',\n InsufficientPermissions: 'STAFF_INSUFFICIENT_PERMISSIONS',\n OwnerOnly: 'STAFF_OWNER_ONLY',\n\n // CRUD\n StaffNotFound: 'STAFF_NOT_FOUND',\n EmailExists: 'STAFF_EMAIL_EXISTS',\n SetupAlreadyComplete: 'STAFF_SETUP_ALREADY_COMPLETE',\n LastOwnerGuard: 'STAFF_LAST_OWNER_GUARD',\n InvalidPermissions: 'STAFF_INVALID_PERMISSIONS',\n\n // Permission Groups\n GroupNotFound: 'STAFF_GROUP_NOT_FOUND',\n GroupIdExists: 'STAFF_GROUP_ID_EXISTS',\n\n // Config\n InvalidConfig: 'STAFF_INVALID_CONFIG',\n} as const;\n\nexport type ErrorCode = (typeof ERROR_CODE)[keyof typeof ERROR_CODE];\n\nexport const ERROR_MESSAGE = {\n InvalidCredentials: 'Invalid email or password',\n AccountInactive: 'Account is deactivated',\n AccountPending: 'Account is pending activation',\n RateLimited: 'Too many login attempts. Please try again later.',\n TokenExpired: 'Token has expired',\n TokenInvalid: 'Invalid token',\n InsufficientPermissions: 'Insufficient permissions',\n OwnerOnly: 'This action requires owner privileges',\n StaffNotFound: 'Staff member not found',\n EmailExists: 'A staff member with this email already exists',\n SetupAlreadyComplete: 'Initial setup has already been completed',\n LastOwnerGuard: 'Cannot deactivate the last active owner',\n InvalidPermissions: 'Edit permissions require corresponding view permissions',\n GroupNotFound: 'Permission group not found',\n GroupIdExists: 'A permission group with this ID already exists',\n InvalidConfig: 'Invalid engine configuration',\n} as const;\n\nexport const DEFAULTS = {\n ListPageSize: 20,\n MaxListPageSize: 100,\n PermissionCacheTtlMs: 5 * 60 * 1000,\n} as const;\n\nexport const DEFAULT_AUTH = {\n staffTokenExpiry: '24h',\n ownerTokenExpiry: '30d',\n permissionCacheTtlMs: 5 * 60 * 1000,\n} as const;\n","import { AlxError } from '@astralibx/core';\nimport { ERROR_CODE, ERROR_MESSAGE } from '../constants/index.js';\n\nexport class AlxStaffError extends AlxError {\n constructor(\n message: string,\n code: string,\n public readonly context?: Record<string, unknown>,\n ) {\n super(message, code);\n this.name = 'AlxStaffError';\n }\n}\n\nexport class AuthenticationError extends AlxStaffError {\n constructor(code: string = ERROR_CODE.InvalidCredentials, message?: string) {\n super(message || ERROR_MESSAGE.InvalidCredentials, code);\n this.name = 'AuthenticationError';\n }\n}\n\nexport class AuthorizationError extends AlxStaffError {\n constructor(code: string = ERROR_CODE.InsufficientPermissions, message?: string) {\n super(message || ERROR_MESSAGE.InsufficientPermissions, code);\n this.name = 'AuthorizationError';\n }\n}\n\nexport class RateLimitError extends AlxStaffError {\n constructor(public readonly retryAfterMs: number) {\n super(ERROR_MESSAGE.RateLimited, ERROR_CODE.RateLimited, { retryAfterMs });\n this.name = 'RateLimitError';\n }\n}\n\nexport class TokenError extends AlxStaffError {\n constructor(code: string = ERROR_CODE.TokenInvalid, message?: string) {\n super(message || ERROR_MESSAGE.TokenInvalid, code);\n this.name = 'TokenError';\n }\n}\n\nexport class StaffNotFoundError extends AlxStaffError {\n constructor(public readonly staffId: string) {\n super(ERROR_MESSAGE.StaffNotFound, ERROR_CODE.StaffNotFound, { staffId });\n this.name = 'StaffNotFoundError';\n }\n}\n\nexport class DuplicateError extends AlxStaffError {\n constructor(code: string, message: string, context?: Record<string, unknown>) {\n super(message, code, context);\n this.name = 'DuplicateError';\n }\n}\n\nexport class SetupError extends AlxStaffError {\n constructor() {\n super(ERROR_MESSAGE.SetupAlreadyComplete, ERROR_CODE.SetupAlreadyComplete);\n this.name = 'SetupError';\n }\n}\n\nexport class LastOwnerError extends AlxStaffError {\n constructor(public readonly staffId: string) {\n super(ERROR_MESSAGE.LastOwnerGuard, ERROR_CODE.LastOwnerGuard, { staffId });\n this.name = 'LastOwnerError';\n }\n}\n\nexport class InvalidPermissionError extends AlxStaffError {\n constructor(public readonly missingViewKeys: string[]) {\n super(ERROR_MESSAGE.InvalidPermissions, ERROR_CODE.InvalidPermissions, { missingViewKeys });\n this.name = 'InvalidPermissionError';\n }\n}\n\nexport class GroupNotFoundError extends AlxStaffError {\n constructor(public readonly groupId: string) {\n super(ERROR_MESSAGE.GroupNotFound, ERROR_CODE.GroupNotFound, { groupId });\n this.name = 'GroupNotFoundError';\n }\n}\n\nexport class InvalidConfigError extends AlxStaffError {\n constructor(public readonly field: string, public readonly reason: string) {\n super(`Invalid config for \"${field}\": ${reason}`, ERROR_CODE.InvalidConfig, { field, reason });\n this.name = 'InvalidConfigError';\n }\n}\n","import type { Model } from 'mongoose';\nimport type { LogAdapter, IPermissionGroupCreateInput, IPermissionGroupUpdateInput } from '@astralibx/staff-types';\nimport type { IPermissionGroupDocument } from '../schemas/permission-group.schema.js';\nimport { DuplicateError, GroupNotFoundError } from '../errors/index.js';\nimport { ERROR_CODE, ERROR_MESSAGE } from '../constants/index.js';\nimport type { PermissionCacheService } from './permission-cache.service.js';\n\nexport class PermissionService {\n constructor(\n private PermissionGroup: Model<IPermissionGroupDocument>,\n private permissionCache: PermissionCacheService,\n private logger: LogAdapter,\n private tenantId?: string,\n ) {}\n\n private get tenantFilter(): Record<string, unknown> {\n return this.tenantId ? { tenantId: this.tenantId } : {};\n }\n\n async listGroups(): Promise<IPermissionGroupDocument[]> {\n return this.PermissionGroup.find(this.tenantFilter).sort({ sortOrder: 1 }).lean() as unknown as IPermissionGroupDocument[];\n }\n\n async createGroup(data: IPermissionGroupCreateInput): Promise<IPermissionGroupDocument> {\n const existing = await this.PermissionGroup.findOne({\n groupId: data.groupId,\n ...this.tenantFilter,\n });\n if (existing) {\n throw new DuplicateError(\n ERROR_CODE.GroupIdExists,\n ERROR_MESSAGE.GroupIdExists,\n { groupId: data.groupId },\n );\n }\n const group = await this.PermissionGroup.create({\n ...data,\n sortOrder: data.sortOrder ?? 0,\n ...this.tenantFilter,\n });\n this.logger.info('Permission group created', { groupId: data.groupId });\n return group.toObject();\n }\n\n async updateGroup(groupId: string, data: IPermissionGroupUpdateInput): Promise<IPermissionGroupDocument> {\n const group = await this.PermissionGroup.findOneAndUpdate(\n { groupId, ...this.tenantFilter },\n { $set: data },\n { new: true },\n ).lean();\n if (!group) {\n throw new GroupNotFoundError(groupId);\n }\n await this.permissionCache.invalidateAll();\n this.logger.info('Permission group updated', { groupId, fields: Object.keys(data) });\n return group as unknown as IPermissionGroupDocument;\n }\n\n async deleteGroup(groupId: string): Promise<void> {\n const result = await this.PermissionGroup.deleteOne({ groupId, ...this.tenantFilter });\n if (result.deletedCount === 0) {\n throw new GroupNotFoundError(groupId);\n }\n await this.permissionCache.invalidateAll();\n this.logger.info('Permission group deleted', { groupId });\n }\n\n async getAllPermissionKeys(): Promise<string[]> {\n const groups = await this.listGroups();\n return groups.flatMap(g => g.permissions.map(p => p.key));\n }\n}\n","import { PERMISSION_TYPE } from '@astralibx/staff-types';\nimport { InvalidPermissionError } from '../errors/index.js';\nimport type { IPermissionGroupDocument } from '../schemas/permission-group.schema.js';\n\n/**\n * Validates that for every edit-type permission, the corresponding view-type permission\n * is also present. Single-level cascade only.\n * Example: 'chat:edit' requires 'chat:view'\n */\nexport function validatePermissionPairs(\n permissions: string[],\n allGroups: IPermissionGroupDocument[],\n): void {\n const allEntries = allGroups.flatMap(g => g.permissions);\n const editKeys = allEntries\n .filter(e => e.type === PERMISSION_TYPE.Edit)\n .map(e => e.key);\n\n const permissionSet = new Set(permissions);\n const missingViewKeys: string[] = [];\n\n for (const editKey of editKeys) {\n if (!permissionSet.has(editKey)) continue;\n const prefix = editKey.substring(0, editKey.lastIndexOf(':'));\n const viewKey = `${prefix}:view`;\n const viewEntry = allEntries.find(e => e.key === viewKey && e.type === PERMISSION_TYPE.View);\n if (viewEntry && !permissionSet.has(viewKey)) {\n missingViewKeys.push(viewKey);\n }\n }\n\n if (missingViewKeys.length > 0) {\n throw new InvalidPermissionError(missingViewKeys);\n }\n}\n","import { z } from 'zod';\n\nexport const StaffEngineConfigSchema = z.object({\n db: z.object({\n connection: z.unknown().refine((v) => v !== undefined && v !== null, {\n message: 'db.connection is required',\n }),\n collectionPrefix: z.string().optional(),\n }),\n redis: z\n .object({\n connection: z.unknown(),\n keyPrefix: z.string().optional(),\n })\n .optional(),\n logger: z\n .object({\n info: z.function(),\n warn: z.function(),\n error: z.function(),\n })\n .optional(),\n tenantId: z.string().optional(),\n auth: z.object({\n jwtSecret: z.string().min(1),\n staffTokenExpiry: z.string().optional(),\n ownerTokenExpiry: z.string().optional(),\n permissionCacheTtlMs: z.number().int().positive().optional(),\n }),\n adapters: z.object({\n hashPassword: z.function(),\n comparePassword: z.function(),\n }),\n hooks: z\n .object({\n onStaffCreated: z.function().optional(),\n onLogin: z.function().optional(),\n onLoginFailed: z.function().optional(),\n onPermissionsChanged: z.function().optional(),\n onStatusChanged: z.function().optional(),\n onMetric: z.function().optional(),\n })\n .optional(),\n options: z\n .object({\n requireEmailUniqueness: z.boolean().optional(),\n allowSelfPasswordChange: z.boolean().optional(),\n rateLimiter: z\n .object({\n windowMs: z.number().int().positive().optional(),\n maxAttempts: z.number().int().positive().optional(),\n })\n .optional(),\n })\n .optional(),\n});\n","import type { Model } from 'mongoose';\nimport type {\n LogAdapter, StaffHooks, StaffAdapters, IStaffCreateInput,\n IStaffUpdateInput, IStaffListFilters, IPaginatedResult,\n} from '@astralibx/staff-types';\nimport { STAFF_ROLE, STAFF_STATUS } from '@astralibx/staff-types';\nimport type { IStaffDocument } from '../schemas/staff.schema.js';\nimport type { IPermissionGroupDocument } from '../schemas/permission-group.schema.js';\nimport type { PermissionCacheService } from './permission-cache.service.js';\nimport {\n DuplicateError, StaffNotFoundError,\n LastOwnerError,\n} from '../errors/index.js';\nimport { ERROR_CODE, ERROR_MESSAGE, DEFAULTS } from '../constants/index.js';\nimport { validatePermissionPairs } from '../validation/index.js';\n\nexport interface StaffServiceDeps {\n Staff: Model<IStaffDocument>;\n PermissionGroup: Model<IPermissionGroupDocument>;\n adapters: StaffAdapters;\n hooks: StaffHooks;\n permissionCache: PermissionCacheService;\n logger: LogAdapter;\n tenantId?: string;\n requireEmailUniqueness: boolean;\n}\n\nexport class StaffService {\n private Staff: Model<IStaffDocument>;\n private PermissionGroup: Model<IPermissionGroupDocument>;\n private adapters: StaffAdapters;\n private hooks: StaffHooks;\n private permissionCache: PermissionCacheService;\n private logger: LogAdapter;\n private tenantId?: string;\n private requireEmailUniqueness: boolean;\n\n constructor(deps: StaffServiceDeps) {\n this.Staff = deps.Staff;\n this.PermissionGroup = deps.PermissionGroup;\n this.adapters = deps.adapters;\n this.hooks = deps.hooks;\n this.permissionCache = deps.permissionCache;\n this.logger = deps.logger;\n this.tenantId = deps.tenantId;\n this.requireEmailUniqueness = deps.requireEmailUniqueness;\n }\n\n private get tenantFilter(): Record<string, unknown> {\n return this.tenantId ? { tenantId: this.tenantId } : {};\n }\n\n async create(data: IStaffCreateInput): Promise<IStaffDocument> {\n if (this.requireEmailUniqueness) {\n const existing = await this.Staff.findOne({\n email: data.email.toLowerCase().trim(),\n ...this.tenantFilter,\n });\n if (existing) {\n throw new DuplicateError(ERROR_CODE.EmailExists, ERROR_MESSAGE.EmailExists, { email: data.email });\n }\n }\n\n const hashedPassword = await this.adapters.hashPassword(data.password);\n const staff = await this.Staff.create({\n ...data,\n email: data.email.toLowerCase().trim(),\n password: hashedPassword,\n role: data.role ?? STAFF_ROLE.Staff,\n status: data.status ?? STAFF_STATUS.Pending,\n permissions: data.permissions ?? [],\n ...this.tenantFilter,\n });\n\n this.logger.info('Staff created', { staffId: staff._id.toString() });\n this.hooks.onStaffCreated?.(staff.toObject());\n return staff.toObject();\n }\n\n async list(filters: IStaffListFilters = {}): Promise<IPaginatedResult<IStaffDocument>> {\n const page = Math.max(1, filters.page ?? 1);\n const limit = Math.min(filters.limit ?? DEFAULTS.ListPageSize, DEFAULTS.MaxListPageSize);\n\n const query: Record<string, unknown> = { ...this.tenantFilter };\n if (filters.status) query.status = filters.status;\n if (filters.role) query.role = filters.role;\n\n const [data, total] = await Promise.all([\n this.Staff.find(query)\n .sort({ createdAt: -1 })\n .skip((page - 1) * limit)\n .limit(limit)\n .lean(),\n this.Staff.countDocuments(query),\n ]);\n\n return {\n data: data as unknown as IStaffDocument[],\n pagination: { page, limit, total, totalPages: Math.ceil(total / limit) },\n };\n }\n\n async getById(staffId: string): Promise<IStaffDocument> {\n const staff = await this.Staff.findOne({ _id: staffId, ...this.tenantFilter }).lean() as unknown as IStaffDocument | null;\n if (!staff) throw new StaffNotFoundError(staffId);\n return staff;\n }\n\n async update(staffId: string, data: IStaffUpdateInput): Promise<IStaffDocument> {\n const updateData: Record<string, unknown> = {};\n if (data.name !== undefined) updateData.name = data.name;\n if (data.email !== undefined) updateData.email = data.email.toLowerCase().trim();\n if (data.metadata !== undefined) updateData.metadata = data.metadata;\n\n if (data.email && this.requireEmailUniqueness) {\n const existing = await this.Staff.findOne({\n email: data.email.toLowerCase().trim(),\n _id: { $ne: staffId },\n ...this.tenantFilter,\n });\n if (existing) {\n throw new DuplicateError(ERROR_CODE.EmailExists, ERROR_MESSAGE.EmailExists, { email: data.email });\n }\n }\n\n const staff = await this.Staff.findOneAndUpdate(\n { _id: staffId, ...this.tenantFilter },\n { $set: updateData },\n { new: true },\n ).lean() as unknown as IStaffDocument | null;\n if (!staff) throw new StaffNotFoundError(staffId);\n\n this.logger.info('Staff updated', { staffId, fields: Object.keys(updateData) });\n return staff;\n }\n\n async updatePermissions(staffId: string, permissions: string[]): Promise<IStaffDocument> {\n const groups = await this.PermissionGroup.find(this.tenantFilter).lean() as unknown as IPermissionGroupDocument[];\n validatePermissionPairs(permissions, groups);\n\n const staff = await this.Staff.findOne({ _id: staffId, ...this.tenantFilter });\n if (!staff) throw new StaffNotFoundError(staffId);\n\n const oldPerms = [...staff.permissions];\n staff.permissions = permissions;\n await staff.save();\n\n await this.permissionCache.invalidate(staffId);\n this.hooks.onPermissionsChanged?.(staffId, oldPerms, permissions);\n this.logger.info('Staff permissions updated', { staffId, count: permissions.length });\n return staff.toObject();\n }\n\n async updateStatus(staffId: string, status: string): Promise<IStaffDocument> {\n const staff = await this.Staff.findOne({ _id: staffId, ...this.tenantFilter });\n if (!staff) throw new StaffNotFoundError(staffId);\n\n if (status === STAFF_STATUS.Inactive && staff.role === STAFF_ROLE.Owner) {\n const activeOwnerCount = await this.Staff.countDocuments({\n role: STAFF_ROLE.Owner,\n status: STAFF_STATUS.Active,\n ...this.tenantFilter,\n });\n if (activeOwnerCount <= 1) throw new LastOwnerError(staffId);\n }\n\n const oldStatus = staff.status;\n staff.status = status as any;\n await staff.save();\n\n await this.permissionCache.invalidate(staffId);\n this.hooks.onStatusChanged?.(staffId, oldStatus, status);\n this.logger.info('Staff status updated', { staffId, oldStatus, newStatus: status });\n return staff.toObject();\n }\n}\n","import jwt from 'jsonwebtoken';\nimport type { Model } from 'mongoose';\nimport type {\n LogAdapter, StaffHooks, StaffAdapters,\n} from '@astralibx/staff-types';\nimport { STAFF_ROLE, STAFF_STATUS } from '@astralibx/staff-types';\nimport type { IStaffDocument } from '../schemas/staff.schema.js';\nimport type { RateLimiterService } from './rate-limiter.service.js';\nimport {\n AuthenticationError, StaffNotFoundError,\n SetupError, RateLimitError,\n} from '../errors/index.js';\nimport { ERROR_CODE, ERROR_MESSAGE } from '../constants/index.js';\n\nexport interface AuthServiceDeps {\n Staff: Model<IStaffDocument>;\n adapters: StaffAdapters;\n hooks: StaffHooks;\n rateLimiter: RateLimiterService;\n logger: LogAdapter;\n tenantId?: string;\n jwtSecret: string;\n staffTokenExpiry: string;\n ownerTokenExpiry: string;\n allowSelfPasswordChange: boolean;\n}\n\nexport class AuthService {\n private Staff: Model<IStaffDocument>;\n private adapters: StaffAdapters;\n private hooks: StaffHooks;\n private rateLimiter: RateLimiterService;\n private logger: LogAdapter;\n private tenantId?: string;\n private jwtSecret: string;\n private staffTokenExpiry: string;\n private ownerTokenExpiry: string;\n private allowSelfPasswordChange: boolean;\n\n constructor(deps: AuthServiceDeps) {\n this.Staff = deps.Staff;\n this.adapters = deps.adapters;\n this.hooks = deps.hooks;\n this.rateLimiter = deps.rateLimiter;\n this.logger = deps.logger;\n this.tenantId = deps.tenantId;\n this.jwtSecret = deps.jwtSecret;\n this.staffTokenExpiry = deps.staffTokenExpiry;\n this.ownerTokenExpiry = deps.ownerTokenExpiry;\n this.allowSelfPasswordChange = deps.allowSelfPasswordChange;\n }\n\n private get tenantFilter(): Record<string, unknown> {\n return this.tenantId ? { tenantId: this.tenantId } : {};\n }\n\n generateToken(staffId: string, role: string): string {\n const expiresIn = role === STAFF_ROLE.Owner ? this.ownerTokenExpiry : this.staffTokenExpiry;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return jwt.sign({ staffId, role }, this.jwtSecret, { expiresIn } as any);\n }\n\n async setupOwner(data: { name: string; email: string; password: string }): Promise<{ staff: IStaffDocument; token: string }> {\n // Race-safe: check count first, then create. If two requests race past the\n // count check, the unique index on {email, tenantId} will reject the second\n // create, which we catch and convert to SetupError.\n const count = await this.Staff.countDocuments(this.tenantFilter);\n if (count > 0) throw new SetupError();\n\n const hashedPassword = await this.adapters.hashPassword(data.password);\n let staff: IStaffDocument;\n try {\n const doc = await this.Staff.create({\n name: data.name,\n email: data.email.toLowerCase().trim(),\n password: hashedPassword,\n role: STAFF_ROLE.Owner,\n status: STAFF_STATUS.Active,\n permissions: [],\n ...this.tenantFilter,\n });\n staff = doc.toObject() as unknown as IStaffDocument;\n } catch (err: unknown) {\n // Race condition: another request created a staff member between our count and create\n if (err && typeof err === 'object' && 'code' in err && (err as any).code === 11000) {\n throw new SetupError();\n }\n throw err;\n }\n const token = this.generateToken(staff._id.toString(), STAFF_ROLE.Owner);\n this.logger.info('Owner setup complete', { staffId: staff._id.toString() });\n this.hooks.onStaffCreated?.(staff);\n this.hooks.onMetric?.({ name: 'staff_setup_complete', value: 1 });\n return { staff, token };\n }\n\n async login(email: string, password: string, ip?: string): Promise<{ staff: IStaffDocument; token: string }> {\n if (ip) {\n const limit = await this.rateLimiter.checkLimit(ip);\n if (!limit.allowed) {\n this.hooks.onLoginFailed?.(email, ip);\n throw new RateLimitError(limit.retryAfterMs!);\n }\n }\n\n const staff = await this.Staff.findOne({\n email: email.toLowerCase().trim(),\n ...this.tenantFilter,\n }).select('+password');\n\n if (!staff) {\n if (ip) await this.rateLimiter.recordAttempt(ip);\n this.hooks.onLoginFailed?.(email, ip);\n throw new AuthenticationError(ERROR_CODE.InvalidCredentials);\n }\n\n const valid = await this.adapters.comparePassword(password, staff.password);\n if (!valid) {\n if (ip) await this.rateLimiter.recordAttempt(ip);\n this.hooks.onLoginFailed?.(email, ip);\n throw new AuthenticationError(ERROR_CODE.InvalidCredentials);\n }\n\n if (staff.status === STAFF_STATUS.Inactive) {\n throw new AuthenticationError(ERROR_CODE.AccountInactive, ERROR_MESSAGE.AccountInactive);\n }\n if (staff.status === STAFF_STATUS.Pending) {\n throw new AuthenticationError(ERROR_CODE.AccountPending, ERROR_MESSAGE.AccountPending);\n }\n\n staff.lastLoginAt = new Date();\n if (ip) staff.lastLoginIp = ip;\n await staff.save();\n\n if (ip) await this.rateLimiter.reset(ip);\n const token = this.generateToken(staff._id.toString(), staff.role);\n this.hooks.onLogin?.(staff.toObject(), ip);\n this.hooks.onMetric?.({ name: 'staff_login', value: 1, labels: { role: staff.role } });\n this.logger.info('Staff login', { staffId: staff._id.toString() });\n\n const staffObj = staff.toObject();\n delete (staffObj as any).password;\n return { staff: staffObj, token };\n }\n\n async resetPassword(staffId: string, newPassword: string): Promise<void> {\n const staff = await this.Staff.findOne({ _id: staffId, ...this.tenantFilter });\n if (!staff) throw new StaffNotFoundError(staffId);\n\n staff.password = await this.adapters.hashPassword(newPassword);\n await staff.save();\n this.logger.info('Staff password reset', { staffId });\n }\n\n async changeOwnPassword(staffId: string, oldPassword: string, newPassword: string): Promise<void> {\n if (!this.allowSelfPasswordChange) {\n throw new AuthenticationError(ERROR_CODE.InsufficientPermissions, 'Self password change is disabled');\n }\n\n const staff = await this.Staff.findOne({ _id: staffId, ...this.tenantFilter }).select('+password');\n if (!staff) throw new StaffNotFoundError(staffId);\n\n const valid = await this.adapters.comparePassword(oldPassword, staff.password);\n if (!valid) throw new AuthenticationError(ERROR_CODE.InvalidCredentials, 'Current password is incorrect');\n\n staff.password = await this.adapters.hashPassword(newPassword);\n await staff.save();\n this.logger.info('Staff changed own password', { staffId });\n }\n}\n","import jwt from 'jsonwebtoken';\nimport type { Request, Response, NextFunction, RequestHandler } from 'express';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport { STAFF_ROLE, STAFF_STATUS } from '@astralibx/staff-types';\nimport type { PermissionCacheService } from '../services/permission-cache.service.js';\nimport type { IStaffDocument } from '../schemas/staff.schema.js';\nimport type { Model } from 'mongoose';\nimport { TokenError, AuthorizationError } from '../errors/index.js';\nimport { ERROR_CODE, ERROR_MESSAGE } from '../constants/index.js';\n\nexport interface StaffUser {\n staffId: string;\n name: string;\n email: string;\n role: string;\n permissions: string[];\n}\n\nexport interface AuthenticatedRequest extends Request {\n user: StaffUser;\n}\n\nexport interface AuthMiddleware {\n verifyToken: RequestHandler;\n resolveStaff: (token: string) => Promise<StaffUser | null>;\n requirePermission: (...keys: string[]) => RequestHandler;\n ownerOnly: RequestHandler;\n requireRole: (...roles: string[]) => RequestHandler;\n}\n\nexport function createAuthMiddleware(\n jwtSecret: string,\n permissionCache: PermissionCacheService,\n StaffModel: Model<IStaffDocument>,\n logger: LogAdapter,\n tenantId?: string,\n): AuthMiddleware {\n\n async function resolveStaffFromToken(token: string): Promise<StaffUser | null> {\n try {\n const payload = jwt.verify(token, jwtSecret) as { staffId: string; role: string };\n if (!payload.staffId || !payload.role) return null;\n\n // Check staff status\n const filter: Record<string, unknown> = { _id: payload.staffId };\n if (tenantId) filter.tenantId = tenantId;\n const staff = await StaffModel.findOne(filter).select('name email status role').lean() as IStaffDocument | null;\n if (!staff) return null;\n if (staff.status !== STAFF_STATUS.Active) return null;\n\n const permissions = await permissionCache.get(payload.staffId);\n return { staffId: payload.staffId, name: staff.name, email: staff.email, role: staff.role, permissions };\n } catch {\n return null;\n }\n }\n\n const verifyToken: RequestHandler = async (req: Request, res: Response, next: NextFunction) => {\n const authHeader = req.headers.authorization;\n if (!authHeader?.startsWith('Bearer ')) {\n res.status(401).json({ success: false, error: ERROR_MESSAGE.TokenInvalid, code: ERROR_CODE.TokenInvalid });\n return;\n }\n\n const token = authHeader.slice(7);\n\n // Distinguish expired vs invalid tokens before full resolution\n try {\n jwt.verify(token, jwtSecret);\n } catch (err: unknown) {\n if (err instanceof jwt.TokenExpiredError) {\n res.status(401).json({ success: false, error: ERROR_MESSAGE.TokenExpired, code: ERROR_CODE.TokenExpired });\n return;\n }\n res.status(401).json({ success: false, error: ERROR_MESSAGE.TokenInvalid, code: ERROR_CODE.TokenInvalid });\n return;\n }\n\n const user = await resolveStaffFromToken(token);\n if (!user) {\n res.status(401).json({ success: false, error: ERROR_MESSAGE.TokenInvalid, code: ERROR_CODE.TokenInvalid });\n return;\n }\n\n (req as AuthenticatedRequest).user = user;\n next();\n };\n\n function requirePermission(...keys: string[]): RequestHandler {\n return (req: Request, res: Response, next: NextFunction) => {\n const user = (req as AuthenticatedRequest).user;\n if (!user) {\n res.status(401).json({ success: false, error: ERROR_MESSAGE.TokenInvalid, code: ERROR_CODE.TokenInvalid });\n return;\n }\n\n // Owner bypasses permission checks\n if (user.role === STAFF_ROLE.Owner) {\n next();\n return;\n }\n\n const permSet = new Set(user.permissions);\n const missing: string[] = [];\n\n for (const key of keys) {\n if (!permSet.has(key)) {\n missing.push(key);\n continue;\n }\n // Single-level edit→view cascade\n if (key.endsWith(':edit')) {\n const prefix = key.substring(0, key.lastIndexOf(':'));\n const viewKey = `${prefix}:view`;\n if (!permSet.has(viewKey)) {\n missing.push(viewKey);\n }\n }\n }\n\n if (missing.length > 0) {\n res.status(403).json({\n success: false,\n error: ERROR_MESSAGE.InsufficientPermissions,\n code: ERROR_CODE.InsufficientPermissions,\n missing,\n });\n return;\n }\n\n next();\n };\n }\n\n const ownerOnly: RequestHandler = (req: Request, res: Response, next: NextFunction) => {\n const user = (req as AuthenticatedRequest).user;\n if (!user || user.role !== STAFF_ROLE.Owner) {\n res.status(403).json({ success: false, error: ERROR_MESSAGE.OwnerOnly, code: ERROR_CODE.OwnerOnly });\n return;\n }\n next();\n };\n\n function requireRole(...roles: string[]): RequestHandler {\n return (req: Request, res: Response, next: NextFunction) => {\n const user = (req as AuthenticatedRequest).user;\n if (!user || !roles.includes(user.role)) {\n res.status(403).json({ success: false, error: ERROR_MESSAGE.InsufficientPermissions, code: ERROR_CODE.InsufficientPermissions });\n return;\n }\n next();\n };\n }\n\n return {\n verifyToken,\n resolveStaff: resolveStaffFromToken,\n requirePermission,\n ownerOnly,\n requireRole,\n };\n}\n","import type { Response } from 'express';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport { sendSuccess, sendError } from '@astralibx/core';\nimport {\n AlxStaffError, AuthenticationError, AuthorizationError,\n RateLimitError, TokenError, StaffNotFoundError, DuplicateError,\n SetupError, LastOwnerError, InvalidPermissionError, GroupNotFoundError,\n} from '../errors/index.js';\n\nexport { sendSuccess };\n\nfunction sendStaffError(res: Response, error: AlxStaffError, status: number): void {\n res.status(status).json({ success: false, error: error.message, code: error.code });\n}\n\nexport function handleStaffError(res: Response, error: unknown, logger: LogAdapter): void {\n if (error instanceof RateLimitError) {\n res.set('Retry-After', String(Math.ceil(error.retryAfterMs / 1000)));\n sendStaffError(res, error, 429);\n } else if (error instanceof AuthenticationError || error instanceof TokenError) {\n sendStaffError(res, error, 401);\n } else if (error instanceof AuthorizationError || error instanceof SetupError) {\n sendStaffError(res, error, 403);\n } else if (error instanceof StaffNotFoundError || error instanceof GroupNotFoundError) {\n sendStaffError(res, error, 404);\n } else if (error instanceof DuplicateError) {\n sendStaffError(res, error, 409);\n } else if (error instanceof LastOwnerError || error instanceof InvalidPermissionError) {\n sendStaffError(res, error, 400);\n } else if (error instanceof AlxStaffError) {\n sendStaffError(res, error, 400);\n } else {\n const message = error instanceof Error ? error.message : 'Unknown error';\n logger.error('Unexpected error', { error: message });\n sendError(res, message, 500);\n }\n}\n","import { Router } from 'express';\nimport type { Request, Response } from 'express';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport type { StaffService } from '../services/staff.service.js';\nimport type { AuthService } from '../services/auth.service.js';\nimport type { AuthMiddleware, AuthenticatedRequest } from '../middleware/auth.middleware.js';\nimport { sendSuccess, handleStaffError } from '../utils/error-handler.js';\n\nexport function createAuthRoutes(\n staffService: StaffService,\n authService: AuthService,\n auth: AuthMiddleware,\n logger: LogAdapter,\n allowSelfPasswordChange: boolean,\n): Router {\n const router = Router();\n\n // POST /setup — public, creates initial owner account\n router.post('/setup', async (req: Request, res: Response) => {\n try {\n const result = await authService.setupOwner(req.body);\n sendSuccess(res, result, 201);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // POST /login — public, returns staff + token\n router.post('/login', async (req: Request, res: Response) => {\n try {\n const { email, password } = req.body as { email: string; password: string };\n const ip = req.ip || req.socket.remoteAddress || '';\n const result = await authService.login(email, password, ip);\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // GET /me — authenticated, returns current staff profile + permissions\n router.get('/me', auth.verifyToken, async (req: Request, res: Response) => {\n try {\n const user = (req as AuthenticatedRequest).user;\n const staff = await staffService.getById(user.staffId);\n sendSuccess(res, { staff, permissions: user.permissions });\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /me/password — only mounted if allowSelfPasswordChange is true\n if (allowSelfPasswordChange) {\n router.put('/me/password', auth.verifyToken, async (req: Request, res: Response) => {\n try {\n const user = (req as AuthenticatedRequest).user;\n const { oldPassword, newPassword } = req.body as { oldPassword: string; newPassword: string };\n await authService.changeOwnPassword(user.staffId, oldPassword, newPassword);\n sendSuccess(res, { message: 'Password changed successfully' });\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n }\n\n return router;\n}\n","import { Router } from 'express';\nimport type { Request, Response } from 'express';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport type { StaffService } from '../services/staff.service.js';\nimport type { AuthService } from '../services/auth.service.js';\nimport { sendSuccess, handleStaffError } from '../utils/error-handler.js';\n\nexport function createStaffRoutes(\n staffService: StaffService,\n logger: LogAdapter,\n authService?: AuthService,\n): Router {\n const router = Router();\n\n // GET / — list staff\n router.get('/', async (req: Request, res: Response) => {\n try {\n const query = req.query as Record<string, string | undefined>;\n const filters: Record<string, unknown> = {};\n if (query['status']) filters['status'] = query['status'];\n if (query['role']) filters['role'] = query['role'];\n if (query['page']) filters['page'] = parseInt(query['page']!, 10);\n if (query['limit']) filters['limit'] = parseInt(query['limit']!, 10);\n const result = await staffService.list(filters as Parameters<typeof staffService.list>[0]);\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // POST / — create staff member\n router.post('/', async (req: Request, res: Response) => {\n try {\n const result = await staffService.create(req.body);\n sendSuccess(res, result, 201);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /:staffId — update staff member\n router.put('/:staffId', async (req: Request, res: Response) => {\n try {\n const result = await staffService.update(req.params['staffId']!, req.body);\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /:staffId/permissions — update staff permissions\n router.put('/:staffId/permissions', async (req: Request, res: Response) => {\n try {\n const result = await staffService.updatePermissions(\n req.params['staffId']!,\n req.body.permissions,\n );\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /:staffId/status — update staff status\n router.put('/:staffId/status', async (req: Request, res: Response) => {\n try {\n const result = await staffService.updateStatus(\n req.params['staffId']!,\n req.body.status,\n );\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /:staffId/password — reset staff password (owner action)\n router.put('/:staffId/password', async (req: Request, res: Response) => {\n try {\n if (!authService) {\n throw new Error('AuthService not available');\n }\n await authService.resetPassword(req.params['staffId']!, req.body.password);\n sendSuccess(res, { message: 'Password reset successfully' });\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n return router;\n}\n","import { Router } from 'express';\nimport type { Request, Response } from 'express';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport type { PermissionService } from '../services/permission.service.js';\nimport type { AuthMiddleware } from '../middleware/auth.middleware.js';\nimport { sendSuccess, handleStaffError } from '../utils/error-handler.js';\n\nexport function createPermissionGroupRoutes(\n permissionService: PermissionService,\n auth: AuthMiddleware,\n logger: LogAdapter,\n): Router {\n const router = Router();\n\n // GET / — authenticated, list all permission groups\n router.get('/', auth.verifyToken, async (req: Request, res: Response) => {\n try {\n const result = await permissionService.listGroups();\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // POST / — owner only, create permission group\n router.post('/', auth.verifyToken, auth.ownerOnly, async (req: Request, res: Response) => {\n try {\n const result = await permissionService.createGroup(req.body);\n sendSuccess(res, result, 201);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // PUT /:groupId — owner only, update permission group\n router.put('/:groupId', auth.verifyToken, auth.ownerOnly, async (req: Request, res: Response) => {\n try {\n const result = await permissionService.updateGroup(req.params['groupId']!, req.body);\n sendSuccess(res, result);\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n // DELETE /:groupId — owner only, delete permission group\n router.delete('/:groupId', auth.verifyToken, auth.ownerOnly, async (req: Request, res: Response) => {\n try {\n await permissionService.deleteGroup(req.params['groupId']!);\n sendSuccess(res, { message: 'Group deleted successfully' });\n } catch (error: unknown) {\n handleStaffError(res, error, logger);\n }\n });\n\n return router;\n}\n","import { Router } from 'express';\nimport type { StaffService } from '../services/staff.service.js';\nimport type { AuthService } from '../services/auth.service.js';\nimport type { PermissionService } from '../services/permission.service.js';\nimport type { AuthMiddleware } from '../middleware/auth.middleware.js';\nimport type { LogAdapter } from '@astralibx/staff-types';\nimport { createAuthRoutes } from './auth.routes.js';\nimport { createStaffRoutes } from './staff.routes.js';\nimport { createPermissionGroupRoutes } from './permission-group.routes.js';\n\nexport interface RouteServices {\n staff: StaffService;\n auth: AuthService;\n permissions: PermissionService;\n}\n\nexport function createRoutes(\n services: RouteServices,\n auth: AuthMiddleware,\n logger: LogAdapter,\n allowSelfPasswordChange: boolean,\n): Router {\n const router = Router();\n\n // Public + authenticated routes (setup, login, /me)\n router.use('/', createAuthRoutes(services.staff, services.auth, auth, logger, allowSelfPasswordChange));\n\n // Owner-only staff CRUD routes\n router.use('/', auth.verifyToken, auth.ownerOnly, createStaffRoutes(services.staff, logger, services.auth));\n\n // Permission group routes (GET is authenticated, CUD is owner-only)\n router.use('/permission-groups', createPermissionGroupRoutes(services.permissions, auth, logger));\n\n return router;\n}\n","import { noopLogger } from '@astralibx/core';\nimport type { Router } from 'express';\nimport type { Model } from 'mongoose';\nimport type { StaffEngineConfig, ResolvedOptions } from '@astralibx/staff-types';\nimport { DEFAULT_OPTIONS } from '@astralibx/staff-types';\nimport { createStaffModel, type IStaffDocument } from './schemas/staff.schema.js';\nimport { createPermissionGroupModel, type IPermissionGroupDocument } from './schemas/permission-group.schema.js';\nimport { RateLimiterService } from './services/rate-limiter.service.js';\nimport { PermissionCacheService } from './services/permission-cache.service.js';\nimport { PermissionService } from './services/permission.service.js';\nimport { StaffService } from './services/staff.service.js';\nimport { AuthService } from './services/auth.service.js';\nimport { createAuthMiddleware, type AuthMiddleware } from './middleware/auth.middleware.js';\nimport { createRoutes } from './routes/index.js';\nimport { DEFAULT_AUTH } from './constants/index.js';\nimport { InvalidConfigError } from './errors/index.js';\nimport { StaffEngineConfigSchema } from './validation/config.schema.js';\n\n// ── Return type ───────────────────────────────────────────────────────────────\n\nexport interface StaffEngine {\n routes: Router;\n auth: AuthMiddleware;\n staff: StaffService;\n authService: AuthService;\n permissions: PermissionService;\n models: {\n Staff: Model<IStaffDocument>;\n PermissionGroup: Model<IPermissionGroupDocument>;\n };\n destroy: () => Promise<void>;\n}\n\n// ── Factory ───────────────────────────────────────────────────────────────────\n\nexport function createStaffEngine(config: StaffEngineConfig): StaffEngine {\n // 1. Validate config with Zod\n const parseResult = StaffEngineConfigSchema.safeParse(config);\n if (!parseResult.success) {\n const issues = parseResult.error.issues\n .map((i) => `${i.path.join('.')}: ${i.message}`)\n .join(', ');\n throw new InvalidConfigError('config', issues);\n }\n\n // 2. Resolve options\n const resolvedOptions: ResolvedOptions = {\n requireEmailUniqueness:\n config.options?.requireEmailUniqueness ?? DEFAULT_OPTIONS.requireEmailUniqueness,\n allowSelfPasswordChange:\n config.options?.allowSelfPasswordChange ?? DEFAULT_OPTIONS.allowSelfPasswordChange,\n rateLimiter: {\n windowMs:\n config.options?.rateLimiter?.windowMs ?? DEFAULT_OPTIONS.rateLimiter.windowMs,\n maxAttempts:\n config.options?.rateLimiter?.maxAttempts ?? DEFAULT_OPTIONS.rateLimiter.maxAttempts,\n },\n };\n\n const resolvedAuth = {\n jwtSecret: config.auth.jwtSecret,\n staffTokenExpiry: config.auth.staffTokenExpiry ?? DEFAULT_AUTH.staffTokenExpiry,\n ownerTokenExpiry: config.auth.ownerTokenExpiry ?? DEFAULT_AUTH.ownerTokenExpiry,\n permissionCacheTtlMs: config.auth.permissionCacheTtlMs ?? DEFAULT_AUTH.permissionCacheTtlMs,\n };\n\n // 3. Set up logger\n const logger = config.logger ?? noopLogger;\n\n // 4. Register mongoose models\n const conn = config.db.connection as import('mongoose').Connection;\n const prefix = config.db.collectionPrefix;\n\n const StaffModel = createStaffModel(conn, prefix);\n const PermissionGroupModel = createPermissionGroupModel(conn, prefix);\n\n // 5. Create services (dependency order)\n const redis = config.redis?.connection ?? null;\n const keyPrefix = config.redis?.keyPrefix ?? 'staff:';\n\n const rateLimiter = new RateLimiterService(\n resolvedOptions.rateLimiter.windowMs,\n resolvedOptions.rateLimiter.maxAttempts,\n redis,\n keyPrefix,\n logger,\n );\n\n const permissionCache = new PermissionCacheService(\n StaffModel,\n resolvedAuth.permissionCacheTtlMs,\n redis,\n keyPrefix,\n logger,\n config.tenantId,\n );\n\n const permissionService = new PermissionService(\n PermissionGroupModel,\n permissionCache,\n logger,\n config.tenantId,\n );\n\n const staffService = new StaffService({\n Staff: StaffModel,\n PermissionGroup: PermissionGroupModel,\n adapters: config.adapters,\n hooks: config.hooks ?? {},\n permissionCache,\n logger,\n tenantId: config.tenantId,\n requireEmailUniqueness: resolvedOptions.requireEmailUniqueness,\n });\n\n const authService = new AuthService({\n Staff: StaffModel,\n adapters: config.adapters,\n hooks: config.hooks ?? {},\n rateLimiter,\n logger,\n tenantId: config.tenantId,\n jwtSecret: resolvedAuth.jwtSecret,\n staffTokenExpiry: resolvedAuth.staffTokenExpiry,\n ownerTokenExpiry: resolvedAuth.ownerTokenExpiry,\n allowSelfPasswordChange: resolvedOptions.allowSelfPasswordChange,\n });\n\n // 6. Create auth middleware\n const auth = createAuthMiddleware(\n resolvedAuth.jwtSecret,\n permissionCache,\n StaffModel,\n logger,\n config.tenantId,\n );\n\n // 7. Create routes\n const routes = createRoutes(\n { staff: staffService, auth: authService, permissions: permissionService },\n auth,\n logger,\n resolvedOptions.allowSelfPasswordChange,\n );\n\n // 8. Return engine object\n async function destroy(): Promise<void> {\n await permissionCache.invalidateAll();\n logger.info('StaffEngine destroyed');\n }\n\n return {\n routes,\n auth,\n staff: staffService,\n authService,\n permissions: permissionService,\n models: { Staff: StaffModel, PermissionGroup: PermissionGroupModel },\n destroy,\n };\n}\n\n// ── Barrel re-exports ─────────────────────────────────────────────────────────\n\nexport * from './constants/index.js';\nexport * from './errors/index.js';\nexport * from './schemas/index.js';\nexport * from './services/index.js';\nexport * from './validation/index.js';\nexport * from './middleware/auth.middleware.js';\nexport * from './utils/error-handler.js';\nexport { createRoutes } from './routes/index.js';\nexport type { StaffEngineConfig, ResolvedOptions } from '@astralibx/staff-types';\nexport { DEFAULT_OPTIONS } from '@astralibx/staff-types';\n"]}
|
package/package.json
CHANGED