@esengine/server 4.2.0 → 4.4.0
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/dist/auth/index.d.ts +3 -3
- package/dist/auth/index.js +8 -5
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/testing/index.d.ts +2 -2
- package/dist/auth/testing/index.js.map +1 -1
- package/dist/{chunk-O3VN2QVN.js → chunk-FACTBKJ3.js} +2 -2
- package/dist/chunk-FACTBKJ3.js.map +1 -0
- package/dist/chunk-I4QQSQ72.js +12 -0
- package/dist/chunk-I4QQSQ72.js.map +1 -0
- package/dist/{chunk-BIAOJF7P.js → chunk-M7VONMZJ.js} +267 -58
- package/dist/chunk-M7VONMZJ.js.map +1 -0
- package/dist/ecs/index.js +2 -2
- package/dist/ecs/index.js.map +1 -1
- package/dist/{index-DyMTy67Q.d.ts → index-lcuKuQsL.d.ts} +106 -9
- package/dist/index.d.ts +28 -6
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/ratelimit/index.d.ts +11 -1
- package/dist/ratelimit/index.js +11 -2
- package/dist/ratelimit/index.js.map +1 -1
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +13 -11
- package/dist/testing/index.js.map +1 -1
- package/dist/{types-AbAXO9Vw.d.ts → types-C7sS8Sfi.d.ts} +1 -1
- package/package.json +5 -9
- package/dist/chunk-BIAOJF7P.js.map +0 -1
- package/dist/chunk-O3VN2QVN.js.map +0 -1
package/dist/auth/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { I as IAuthContext, A as AuthResult, a as IAuthProvider, b as AuthServerConfig, c as AuthGameServer, d as AuthRoomConfig, R as RequireAuthOptions, e as RequireRoleOptions } from '../types-
|
|
2
|
-
export { i as AuthApiContext, h as AuthConnection, g as AuthConnectionData, f as AuthErrorCode, j as AuthMsgContext, C as ConnectionRequest } from '../types-
|
|
3
|
-
import { G as GameServer,
|
|
1
|
+
import { I as IAuthContext, A as AuthResult, a as IAuthProvider, b as AuthServerConfig, c as AuthGameServer, d as AuthRoomConfig, R as RequireAuthOptions, e as RequireRoleOptions } from '../types-C7sS8Sfi.js';
|
|
2
|
+
export { i as AuthApiContext, h as AuthConnection, g as AuthConnectionData, f as AuthErrorCode, j as AuthMsgContext, C as ConnectionRequest } from '../types-C7sS8Sfi.js';
|
|
3
|
+
import { G as GameServer, c as ServerConnection } from '../index-lcuKuQsL.js';
|
|
4
4
|
import { R as Room, P as Player } from '../Room-BnKpl5Sj.js';
|
|
5
5
|
import '@esengine/rpc';
|
|
6
6
|
import 'node:http';
|
package/dist/auth/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createLogger } from '../chunk-I4QQSQ72.js';
|
|
1
2
|
import { __name, __publicField } from '../chunk-T626JPC7.js';
|
|
2
3
|
import * as jwt from 'jsonwebtoken';
|
|
3
4
|
import { randomBytes } from 'crypto';
|
|
@@ -414,6 +415,7 @@ function createSessionAuthProvider(config) {
|
|
|
414
415
|
__name(createSessionAuthProvider, "createSessionAuthProvider");
|
|
415
416
|
|
|
416
417
|
// src/auth/mixin/withAuth.ts
|
|
418
|
+
var logger = createLogger("Auth");
|
|
417
419
|
var AUTH_CONTEXT_KEY = /* @__PURE__ */ Symbol("authContext");
|
|
418
420
|
function getAuthContext(conn) {
|
|
419
421
|
const data = conn.data;
|
|
@@ -481,7 +483,7 @@ function withAuth(server, config) {
|
|
|
481
483
|
}
|
|
482
484
|
}
|
|
483
485
|
} catch (error) {
|
|
484
|
-
|
|
486
|
+
logger.error("Error during auto-authentication:", error);
|
|
485
487
|
}
|
|
486
488
|
}
|
|
487
489
|
if (originalOnConnect) {
|
|
@@ -521,6 +523,7 @@ function requireRole(conn, roles, options) {
|
|
|
521
523
|
__name(requireRole, "requireRole");
|
|
522
524
|
|
|
523
525
|
// src/auth/mixin/withRoomAuth.ts
|
|
526
|
+
var logger2 = createLogger("AuthRoom");
|
|
524
527
|
var playerAuthContexts = /* @__PURE__ */ new WeakMap();
|
|
525
528
|
function wrapPlayerWithAuth(player, authContext) {
|
|
526
529
|
playerAuthContexts.set(player, authContext);
|
|
@@ -555,14 +558,14 @@ function withRoomAuth(Base, config = {}) {
|
|
|
555
558
|
const conn = player.connection ?? player._conn;
|
|
556
559
|
const authContext = conn ? getAuthContext(conn) ?? createGuestContext() : createGuestContext();
|
|
557
560
|
if (requireAuth2 && !authContext.isAuthenticated) {
|
|
558
|
-
|
|
561
|
+
logger2.warn(`Rejected unauthenticated player: ${player.id}`);
|
|
559
562
|
this.kick(player, "Authentication required");
|
|
560
563
|
return;
|
|
561
564
|
}
|
|
562
565
|
if (allowedRoles.length > 0) {
|
|
563
566
|
const hasRole = roleCheckMode === "any" ? authContext.hasAnyRole(allowedRoles) : authContext.hasAllRoles(allowedRoles);
|
|
564
567
|
if (!hasRole) {
|
|
565
|
-
|
|
568
|
+
logger2.warn(`Rejected player ${player.id}: insufficient roles`);
|
|
566
569
|
this.kick(player, "Insufficient permissions");
|
|
567
570
|
return;
|
|
568
571
|
}
|
|
@@ -572,12 +575,12 @@ function withRoomAuth(Base, config = {}) {
|
|
|
572
575
|
try {
|
|
573
576
|
const allowed = await this.onAuth(authPlayer);
|
|
574
577
|
if (!allowed) {
|
|
575
|
-
|
|
578
|
+
logger2.warn(`Rejected player ${player.id}: onAuth returned false`);
|
|
576
579
|
this.kick(player, "Authentication rejected");
|
|
577
580
|
return;
|
|
578
581
|
}
|
|
579
582
|
} catch (error) {
|
|
580
|
-
|
|
583
|
+
logger2.error(`Error in onAuth for player ${player.id}:`, error);
|
|
581
584
|
this.kick(player, "Authentication error");
|
|
582
585
|
return;
|
|
583
586
|
}
|
package/dist/auth/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/auth/context.ts","../../src/auth/providers/JwtAuthProvider.ts","../../src/auth/providers/SessionAuthProvider.ts","../../src/auth/mixin/withAuth.ts","../../src/auth/mixin/withRoomAuth.ts","../../src/auth/decorators/requireAuth.ts","../../src/auth/decorators/requireRole.ts"],"names":["defaultUserExtractor","getId","user","u","id","String","userId","sub","getRoles","Array","isArray","roles","filter","r","role","AuthContext","extractor","_isAuthenticated","_user","_userId","_roles","_authenticatedAt","_expiresAt","_extractor","isAuthenticated","Date","now","authenticatedAt","expiresAt","hasRole","includes","hasAnyRole","some","hasAllRoles","every","setAuthenticated","result","success","clear","createGuestContext","createAuthContext","context","JwtAuthProvider","config","name","_config","algorithm","expiresIn","verify","token","error","errorCode","verifyOptions","algorithms","issuer","audience","payload","secret","getUser","exp","undefined","err","message","refresh","decode","iat","nbf","restPayload","newToken","sign","signOptions","createJwtAuthProvider","SessionAuthProvider","sessionTTL","prefix","autoRenew","_getKey","sessionId","key","session","storage","get","validateUser","isValid","lastActiveAt","set","createdAt","revoke","delete","createSession","data","_generateSessionId","getSession","updateSession","randomBytes","toString","createSessionAuthProvider","AUTH_CONTEXT_KEY","getAuthContext","conn","setAuthContext","withAuth","server","provider","extractCredentials","autoAuthOnConnect","disconnectOnAuthFailure","onAuthSuccess","onAuthFailure","originalConnections","connections","connectionAuthMap","WeakMap","authServer","authProvider","authenticate","credentials","authContext","originalOnConnect","_onConnect","req","connReq","close","console","originalOnDisconnect","_onDisconnect","requireAuthentication","options","auth","Error","errorMessage","requireRole","roleArray","mode","playerAuthContexts","wrapPlayerWithAuth","player","Object","defineProperty","enumerable","configurable","withRoomAuth","Base","requireAuth","allowedRoles","roleCheckMode","AuthRoom","args","_originalOnJoin","onJoin","bind","_authOnJoin","connection","_conn","warn","kick","length","authPlayer","onAuth","allowed","getAuthPlayer","getPlayer","getAuthPlayers","players","getPlayersByRole","p","getPlayerByUserId","find","AuthRoomBase","authConfig","AUTH_METADATA_KEY","getAuthMetadata","target","propertyKey","metadata","setAuthMetadata","Map","descriptor","existing","roleMode"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @zh 认证上下文实现\n * @en Authentication context implementation\n */\n\nimport type { IAuthContext, AuthResult } from './types.js';\n\n/**\n * @zh 用户信息提取器\n * @en User info extractor\n */\nexport interface UserInfoExtractor<TUser> {\n /**\n * @zh 提取用户 ID\n * @en Extract user ID\n */\n getId(user: TUser): string;\n\n /**\n * @zh 提取用户角色\n * @en Extract user roles\n */\n getRoles(user: TUser): string[];\n}\n\n/**\n * @zh 默认用户信息提取器\n * @en Default user info extractor\n */\nexport const defaultUserExtractor: UserInfoExtractor<unknown> = {\n getId(user: unknown): string {\n if (user && typeof user === 'object') {\n const u = user as Record<string, unknown>;\n if (typeof u.id === 'string') return u.id;\n if (typeof u.id === 'number') return String(u.id);\n if (typeof u.userId === 'string') return u.userId;\n if (typeof u.userId === 'number') return String(u.userId);\n if (typeof u.sub === 'string') return u.sub;\n }\n return '';\n },\n\n getRoles(user: unknown): string[] {\n if (user && typeof user === 'object') {\n const u = user as Record<string, unknown>;\n if (Array.isArray(u.roles)) {\n return u.roles.filter((r): r is string => typeof r === 'string');\n }\n if (typeof u.role === 'string') {\n return [u.role];\n }\n }\n return [];\n }\n};\n\n/**\n * @zh 认证上下文\n * @en Authentication context\n *\n * @zh 存储连接的认证状态\n * @en Stores authentication state for a connection\n */\nexport class AuthContext<TUser = unknown> implements IAuthContext<TUser> {\n private _isAuthenticated: boolean = false;\n private _user: TUser | null = null;\n private _userId: string | null = null;\n private _roles: string[] = [];\n private _authenticatedAt: number | null = null;\n private _expiresAt: number | null = null;\n private _extractor: UserInfoExtractor<TUser>;\n\n constructor(extractor?: UserInfoExtractor<TUser>) {\n this._extractor = (extractor ?? defaultUserExtractor) as UserInfoExtractor<TUser>;\n }\n\n /**\n * @zh 是否已认证\n * @en Whether authenticated\n */\n get isAuthenticated(): boolean {\n if (this._expiresAt && Date.now() > this._expiresAt) {\n return false;\n }\n return this._isAuthenticated;\n }\n\n /**\n * @zh 用户信息\n * @en User information\n */\n get user(): TUser | null {\n return this._user;\n }\n\n /**\n * @zh 用户 ID\n * @en User ID\n */\n get userId(): string | null {\n return this._userId;\n }\n\n /**\n * @zh 用户角色\n * @en User roles\n */\n get roles(): ReadonlyArray<string> {\n return this._roles;\n }\n\n /**\n * @zh 认证时间\n * @en Authentication timestamp\n */\n get authenticatedAt(): number | null {\n return this._authenticatedAt;\n }\n\n /**\n * @zh 令牌过期时间\n * @en Token expiration time\n */\n get expiresAt(): number | null {\n return this._expiresAt;\n }\n\n /**\n * @zh 检查是否有指定角色\n * @en Check if has specified role\n */\n hasRole(role: string): boolean {\n return this._roles.includes(role);\n }\n\n /**\n * @zh 检查是否有任一指定角色\n * @en Check if has any of specified roles\n */\n hasAnyRole(roles: string[]): boolean {\n return roles.some(role => this._roles.includes(role));\n }\n\n /**\n * @zh 检查是否有所有指定角色\n * @en Check if has all specified roles\n */\n hasAllRoles(roles: string[]): boolean {\n return roles.every(role => this._roles.includes(role));\n }\n\n /**\n * @zh 设置认证结果\n * @en Set authentication result\n */\n setAuthenticated(result: AuthResult<TUser>): void {\n if (result.success && result.user) {\n this._isAuthenticated = true;\n this._user = result.user;\n this._userId = this._extractor.getId(result.user);\n this._roles = this._extractor.getRoles(result.user);\n this._authenticatedAt = Date.now();\n this._expiresAt = result.expiresAt ?? null;\n } else {\n this.clear();\n }\n }\n\n /**\n * @zh 清除认证状态\n * @en Clear authentication state\n */\n clear(): void {\n this._isAuthenticated = false;\n this._user = null;\n this._userId = null;\n this._roles = [];\n this._authenticatedAt = null;\n this._expiresAt = null;\n }\n}\n\n/**\n * @zh 创建访客认证上下文\n * @en Create guest auth context\n */\nexport function createGuestContext<TUser = unknown>(): IAuthContext<TUser> {\n return new AuthContext<TUser>();\n}\n\n/**\n * @zh 从认证结果创建认证上下文\n * @en Create auth context from auth result\n */\nexport function createAuthContext<TUser = unknown>(\n result: AuthResult<TUser>,\n extractor?: UserInfoExtractor<TUser>\n): AuthContext<TUser> {\n const context = new AuthContext<TUser>(extractor);\n context.setAuthenticated(result);\n return context;\n}\n","/**\n * @zh JWT 认证提供者\n * @en JWT authentication provider\n */\n\nimport type { IAuthProvider, AuthResult, AuthErrorCode } from '../types.js';\nimport * as jwt from 'jsonwebtoken';\n\n/**\n * @zh JWT 载荷\n * @en JWT payload\n */\nexport interface JwtPayload {\n /**\n * @zh 主题(用户 ID)\n * @en Subject (user ID)\n */\n sub?: string;\n\n /**\n * @zh 签发时间\n * @en Issued at\n */\n iat?: number;\n\n /**\n * @zh 过期时间\n * @en Expiration time\n */\n exp?: number;\n\n /**\n * @zh 自定义字段\n * @en Custom fields\n */\n [key: string]: unknown;\n}\n\n/**\n * @zh JWT 认证配置\n * @en JWT authentication configuration\n */\nexport interface JwtAuthConfig<TUser = unknown> {\n /**\n * @zh 密钥\n * @en Secret key\n */\n secret: string;\n\n /**\n * @zh 算法\n * @en Algorithm\n * @defaultValue 'HS256'\n */\n algorithm?: 'HS256' | 'HS384' | 'HS512' | 'RS256' | 'RS384' | 'RS512';\n\n /**\n * @zh 令牌过期时间(秒)\n * @en Token expiration in seconds\n * @defaultValue 3600\n */\n expiresIn?: number;\n\n /**\n * @zh 从载荷获取用户信息\n * @en Get user from payload\n */\n getUser?: (payload: JwtPayload) => TUser | Promise<TUser | null> | null;\n\n /**\n * @zh 签发者\n * @en Issuer\n */\n issuer?: string;\n\n /**\n * @zh 受众\n * @en Audience\n */\n audience?: string;\n}\n\n/**\n * @zh JWT 认证提供者\n * @en JWT authentication provider\n *\n * @zh 使用 jsonwebtoken 库实现 JWT 认证\n * @en Uses jsonwebtoken library for JWT authentication\n *\n * @example\n * ```typescript\n * const jwtProvider = createJwtAuthProvider({\n * secret: 'your-secret-key',\n * expiresIn: 3600,\n * getUser: async (payload) => {\n * return await db.users.findById(payload.sub);\n * }\n * });\n * ```\n */\nexport class JwtAuthProvider<TUser = unknown> implements IAuthProvider<TUser, string> {\n readonly name = 'jwt';\n\n private _config: Required<Pick<JwtAuthConfig<TUser>, 'secret' | 'algorithm' | 'expiresIn'>> & JwtAuthConfig<TUser>;\n\n constructor(config: JwtAuthConfig<TUser>) {\n this._config = {\n algorithm: 'HS256',\n expiresIn: 3600,\n ...config\n };\n }\n\n /**\n * @zh 验证令牌\n * @en Verify token\n */\n async verify(token: string): Promise<AuthResult<TUser>> {\n if (!token) {\n return {\n success: false,\n error: 'Token is required',\n errorCode: 'INVALID_TOKEN'\n };\n }\n\n try {\n const verifyOptions: jwt.VerifyOptions = {\n algorithms: [this._config.algorithm]\n };\n if (this._config.issuer) {\n verifyOptions.issuer = this._config.issuer;\n }\n if (this._config.audience) {\n verifyOptions.audience = this._config.audience;\n }\n const payload = jwt.verify(token, this._config.secret, verifyOptions) as JwtPayload;\n\n let user: TUser | null = null;\n\n if (this._config.getUser) {\n user = await this._config.getUser(payload);\n if (!user) {\n return {\n success: false,\n error: 'User not found',\n errorCode: 'USER_NOT_FOUND'\n };\n }\n } else {\n user = payload as unknown as TUser;\n }\n\n return {\n success: true,\n user,\n token,\n expiresAt: payload.exp ? payload.exp * 1000 : undefined\n };\n } catch (error) {\n const err = error as Error;\n\n if (err.name === 'TokenExpiredError') {\n return {\n success: false,\n error: 'Token has expired',\n errorCode: 'EXPIRED_TOKEN'\n };\n }\n\n return {\n success: false,\n error: err.message || 'Invalid token',\n errorCode: 'INVALID_TOKEN'\n };\n }\n }\n\n /**\n * @zh 刷新令牌\n * @en Refresh token\n */\n async refresh(token: string): Promise<AuthResult<TUser>> {\n const result = await this.verify(token);\n\n if (!result.success || !result.user) {\n return result;\n }\n\n const payload = jwt.decode(token) as JwtPayload;\n\n // Remove JWT standard claims that will be regenerated\n const { iat, exp, nbf, ...restPayload } = payload;\n\n const newToken = this.sign(restPayload);\n\n return {\n success: true,\n user: result.user,\n token: newToken,\n expiresAt: Date.now() + this._config.expiresIn * 1000\n };\n }\n\n /**\n * @zh 生成令牌\n * @en Generate token\n */\n sign(payload: Record<string, unknown>): string {\n const signOptions: jwt.SignOptions = {\n algorithm: this._config.algorithm,\n expiresIn: this._config.expiresIn\n };\n if (this._config.issuer) {\n signOptions.issuer = this._config.issuer;\n }\n if (this._config.audience) {\n signOptions.audience = this._config.audience;\n }\n return jwt.sign(payload, this._config.secret, signOptions);\n }\n\n /**\n * @zh 解码令牌(不验证)\n * @en Decode token (without verification)\n */\n decode(token: string): JwtPayload | null {\n return jwt.decode(token) as JwtPayload | null;\n }\n}\n\n/**\n * @zh 创建 JWT 认证提供者\n * @en Create JWT authentication provider\n *\n * @example\n * ```typescript\n * import { createJwtAuthProvider } from '@esengine/server/auth';\n *\n * const jwtProvider = createJwtAuthProvider({\n * secret: process.env.JWT_SECRET!,\n * expiresIn: 3600,\n * getUser: async (payload) => {\n * return { id: payload.sub, name: payload.name };\n * }\n * });\n * ```\n */\nexport function createJwtAuthProvider<TUser = unknown>(\n config: JwtAuthConfig<TUser>\n): JwtAuthProvider<TUser> {\n return new JwtAuthProvider<TUser>(config);\n}\n","/**\n * @zh Session 认证提供者\n * @en Session authentication provider\n */\n\nimport { randomBytes } from 'crypto';\nimport type { IAuthProvider, AuthResult } from '../types.js';\n\n/**\n * @zh Session 存储接口(兼容 ITransactionStorage)\n * @en Session storage interface (compatible with ITransactionStorage)\n */\nexport interface ISessionStorage {\n get<T>(key: string): Promise<T | null>;\n set<T>(key: string, value: T, ttl?: number): Promise<void>;\n delete(key: string): Promise<boolean>;\n}\n\n/**\n * @zh Session 数据\n * @en Session data\n */\nexport interface SessionData<TUser = unknown> {\n /**\n * @zh 用户信息\n * @en User information\n */\n user: TUser;\n\n /**\n * @zh 创建时间\n * @en Created at\n */\n createdAt: number;\n\n /**\n * @zh 最后活跃时间\n * @en Last active at\n */\n lastActiveAt: number;\n\n /**\n * @zh 自定义数据\n * @en Custom data\n */\n data?: Record<string, unknown>;\n}\n\n/**\n * @zh Session 认证配置\n * @en Session authentication configuration\n */\nexport interface SessionAuthConfig<TUser = unknown> {\n /**\n * @zh Session 存储\n * @en Session storage\n */\n storage: ISessionStorage;\n\n /**\n * @zh Session 过期时间(毫秒)\n * @en Session expiration in milliseconds\n * @defaultValue 86400000 (24h)\n */\n sessionTTL?: number;\n\n /**\n * @zh Session 键前缀\n * @en Session key prefix\n * @defaultValue 'session:'\n */\n prefix?: string;\n\n /**\n * @zh 验证用户(可选额外验证)\n * @en Validate user (optional extra validation)\n */\n validateUser?: (user: TUser) => boolean | Promise<boolean>;\n\n /**\n * @zh 是否自动续期\n * @en Auto renew session\n * @defaultValue true\n */\n autoRenew?: boolean;\n}\n\n/**\n * @zh Session 认证提供者\n * @en Session authentication provider\n *\n * @zh 基于存储的会话认证,支持 Redis、MongoDB 等后端\n * @en Storage-based session authentication, supports Redis, MongoDB, etc.\n *\n * @example\n * ```typescript\n * import { createSessionAuthProvider } from '@esengine/server/auth';\n * import { createRedisStorage } from '@esengine/transaction';\n *\n * const sessionProvider = createSessionAuthProvider({\n * storage: createRedisStorage({ factory: () => new Redis() }),\n * sessionTTL: 86400000, // 24 hours\n * });\n * ```\n */\nexport class SessionAuthProvider<TUser = unknown> implements IAuthProvider<TUser, string> {\n readonly name = 'session';\n\n private _config: Required<Pick<SessionAuthConfig<TUser>, 'sessionTTL' | 'prefix' | 'autoRenew'>> & SessionAuthConfig<TUser>;\n\n constructor(config: SessionAuthConfig<TUser>) {\n this._config = {\n sessionTTL: 86400000,\n prefix: 'session:',\n autoRenew: true,\n ...config\n };\n }\n\n /**\n * @zh 获取存储键\n * @en Get storage key\n */\n private _getKey(sessionId: string): string {\n return `${this._config.prefix}${sessionId}`;\n }\n\n /**\n * @zh 验证 Session\n * @en Verify session\n */\n async verify(sessionId: string): Promise<AuthResult<TUser>> {\n if (!sessionId) {\n return {\n success: false,\n error: 'Session ID is required',\n errorCode: 'INVALID_TOKEN'\n };\n }\n\n const key = this._getKey(sessionId);\n const session = await this._config.storage.get<SessionData<TUser>>(key);\n\n if (!session) {\n return {\n success: false,\n error: 'Session not found or expired',\n errorCode: 'EXPIRED_TOKEN'\n };\n }\n\n if (this._config.validateUser) {\n const isValid = await this._config.validateUser(session.user);\n if (!isValid) {\n return {\n success: false,\n error: 'User validation failed',\n errorCode: 'ACCOUNT_DISABLED'\n };\n }\n }\n\n if (this._config.autoRenew) {\n session.lastActiveAt = Date.now();\n await this._config.storage.set(key, session, this._config.sessionTTL);\n }\n\n return {\n success: true,\n user: session.user,\n token: sessionId,\n expiresAt: session.createdAt + this._config.sessionTTL\n };\n }\n\n /**\n * @zh 刷新 Session\n * @en Refresh session\n */\n async refresh(sessionId: string): Promise<AuthResult<TUser>> {\n const result = await this.verify(sessionId);\n\n if (!result.success) {\n return result;\n }\n\n const key = this._getKey(sessionId);\n const session = await this._config.storage.get<SessionData<TUser>>(key);\n\n if (session) {\n session.lastActiveAt = Date.now();\n await this._config.storage.set(key, session, this._config.sessionTTL);\n }\n\n return {\n ...result,\n expiresAt: Date.now() + this._config.sessionTTL\n };\n }\n\n /**\n * @zh 撤销 Session\n * @en Revoke session\n */\n async revoke(sessionId: string): Promise<boolean> {\n const key = this._getKey(sessionId);\n return await this._config.storage.delete(key);\n }\n\n /**\n * @zh 创建 Session\n * @en Create session\n */\n async createSession(user: TUser, data?: Record<string, unknown>): Promise<string> {\n const sessionId = this._generateSessionId();\n const key = this._getKey(sessionId);\n\n const session: SessionData<TUser> = {\n user,\n createdAt: Date.now(),\n lastActiveAt: Date.now(),\n data\n };\n\n await this._config.storage.set(key, session, this._config.sessionTTL);\n\n return sessionId;\n }\n\n /**\n * @zh 获取 Session 数据\n * @en Get session data\n */\n async getSession(sessionId: string): Promise<SessionData<TUser> | null> {\n const key = this._getKey(sessionId);\n return await this._config.storage.get<SessionData<TUser>>(key);\n }\n\n /**\n * @zh 更新 Session 数据\n * @en Update session data\n */\n async updateSession(sessionId: string, data: Record<string, unknown>): Promise<boolean> {\n const key = this._getKey(sessionId);\n const session = await this._config.storage.get<SessionData<TUser>>(key);\n\n if (!session) {\n return false;\n }\n\n session.data = { ...session.data, ...data };\n session.lastActiveAt = Date.now();\n await this._config.storage.set(key, session, this._config.sessionTTL);\n\n return true;\n }\n\n /**\n * @zh 生成 Session ID(使用加密安全的随机数)\n * @en Generate session ID (using cryptographically secure random)\n */\n private _generateSessionId(): string {\n return randomBytes(32).toString('hex');\n }\n}\n\n/**\n * @zh 创建 Session 认证提供者\n * @en Create session authentication provider\n *\n * @example\n * ```typescript\n * import { createSessionAuthProvider } from '@esengine/server/auth';\n * import { MemoryStorage } from '@esengine/transaction';\n *\n * const sessionProvider = createSessionAuthProvider({\n * storage: new MemoryStorage(),\n * sessionTTL: 3600000, // 1 hour\n * });\n *\n * // Create a session\n * const sessionId = await sessionProvider.createSession({ id: '1', name: 'Alice' });\n *\n * // Verify session\n * const result = await sessionProvider.verify(sessionId);\n * ```\n */\nexport function createSessionAuthProvider<TUser = unknown>(\n config: SessionAuthConfig<TUser>\n): SessionAuthProvider<TUser> {\n return new SessionAuthProvider<TUser>(config);\n}\n","/**\n * @zh 服务器认证 Mixin\n * @en Server authentication mixin\n */\n\nimport type { ServerConnection, GameServer } from '../../types/index.js';\nimport type {\n IAuthProvider,\n AuthResult,\n AuthServerConfig,\n AuthGameServer,\n IAuthContext,\n ConnectionRequest\n} from '../types.js';\nimport { AuthContext } from '../context.js';\n\n/**\n * @zh 认证数据键\n * @en Auth data key\n */\nconst AUTH_CONTEXT_KEY = Symbol('authContext');\n\n/**\n * @zh 获取连接的认证上下文\n * @en Get auth context for connection\n */\nexport function getAuthContext<TUser = unknown>(conn: ServerConnection): IAuthContext<TUser> | null {\n const data = conn.data as Record<symbol, unknown>;\n return (data[AUTH_CONTEXT_KEY] as IAuthContext<TUser>) ?? null;\n}\n\n/**\n * @zh 设置连接的认证上下文\n * @en Set auth context for connection\n */\nexport function setAuthContext<TUser = unknown>(conn: ServerConnection, context: IAuthContext<TUser>): void {\n const data = conn.data as Record<symbol, unknown>;\n data[AUTH_CONTEXT_KEY] = context;\n}\n\n/**\n * @zh 包装服务器添加认证功能\n * @en Wrap server with authentication functionality\n *\n * @zh 使用 mixin 模式为服务器添加认证能力,不修改原始服务器\n * @en Uses mixin pattern to add authentication to server without modifying original\n *\n * @example\n * ```typescript\n * import { createServer } from '@esengine/server';\n * import { withAuth, createJwtAuthProvider } from '@esengine/server/auth';\n *\n * const jwtProvider = createJwtAuthProvider({\n * secret: 'your-secret-key',\n * expiresIn: 3600,\n * });\n *\n * const server = withAuth(await createServer({ port: 3000 }), {\n * provider: jwtProvider,\n * extractCredentials: (req) => {\n * const url = new URL(req.url, 'http://localhost');\n * return url.searchParams.get('token');\n * },\n * onAuthSuccess: (conn, user) => {\n * console.log(`User ${user.name} authenticated`);\n * },\n * onAuthFailure: (conn, error) => {\n * console.log(`Auth failed: ${error.error}`);\n * }\n * });\n *\n * await server.start();\n * ```\n */\nexport function withAuth<TUser = unknown>(\n server: GameServer,\n config: AuthServerConfig<TUser>\n): AuthGameServer<TUser> {\n const {\n provider,\n extractCredentials,\n autoAuthOnConnect = true,\n disconnectOnAuthFailure = false,\n onAuthSuccess,\n onAuthFailure\n } = config;\n\n const originalConnections = server.connections;\n const connectionAuthMap = new WeakMap<ServerConnection, AuthContext<TUser>>();\n\n const authServer: AuthGameServer<TUser> = {\n ...server,\n\n get authProvider(): IAuthProvider<TUser> {\n return provider;\n },\n\n async authenticate(\n conn: ServerConnection,\n credentials: unknown\n ): Promise<AuthResult<TUser>> {\n const result = await provider.verify(credentials as never);\n\n let authContext = connectionAuthMap.get(conn);\n if (!authContext) {\n authContext = new AuthContext<TUser>();\n connectionAuthMap.set(conn, authContext);\n setAuthContext(conn, authContext);\n }\n\n if (result.success) {\n authContext.setAuthenticated(result);\n await onAuthSuccess?.(conn, result.user!);\n } else {\n authContext.clear();\n await onAuthFailure?.(conn, result);\n }\n\n return result;\n },\n\n getAuthContext(conn: ServerConnection): IAuthContext<TUser> | null {\n return connectionAuthMap.get(conn) ?? null;\n },\n\n get connections(): ReadonlyArray<ServerConnection> {\n return originalConnections;\n }\n };\n\n const originalOnConnect = (server as any)._onConnect;\n (server as any)._onConnect = async (conn: ServerConnection, req?: unknown) => {\n const authContext = new AuthContext<TUser>();\n connectionAuthMap.set(conn, authContext);\n setAuthContext(conn, authContext);\n\n if (autoAuthOnConnect && extractCredentials && req) {\n try {\n const connReq = req as ConnectionRequest;\n const credentials = await extractCredentials(connReq);\n\n if (credentials) {\n const result = await provider.verify(credentials as never);\n\n if (result.success) {\n authContext.setAuthenticated(result);\n await onAuthSuccess?.(conn, result.user!);\n } else {\n await onAuthFailure?.(conn, result);\n\n if (disconnectOnAuthFailure) {\n (conn as any).close?.();\n return;\n }\n }\n }\n } catch (error) {\n console.error('[Auth] Error during auto-authentication:', error);\n }\n }\n\n if (originalOnConnect) {\n await originalOnConnect(conn, req);\n }\n };\n\n const originalOnDisconnect = (server as any)._onDisconnect;\n (server as any)._onDisconnect = async (conn: ServerConnection) => {\n connectionAuthMap.delete(conn);\n\n if (originalOnDisconnect) {\n await originalOnDisconnect(conn);\n }\n };\n\n return authServer;\n}\n\n/**\n * @zh 创建认证中间件\n * @en Create authentication middleware\n *\n * @zh 用于在 API 处理器中检查认证状态\n * @en Used to check authentication status in API handlers\n */\nexport function requireAuthentication<TUser = unknown>(\n conn: ServerConnection,\n options?: { errorMessage?: string }\n): IAuthContext<TUser> {\n const auth = getAuthContext<TUser>(conn);\n\n if (!auth || !auth.isAuthenticated) {\n throw new Error(options?.errorMessage ?? 'Authentication required');\n }\n\n return auth;\n}\n\n/**\n * @zh 创建角色检查中间件\n * @en Create role check middleware\n */\nexport function requireRole<TUser = unknown>(\n conn: ServerConnection,\n roles: string | string[],\n options?: { mode?: 'any' | 'all'; errorMessage?: string }\n): IAuthContext<TUser> {\n const auth = requireAuthentication<TUser>(conn);\n const roleArray = Array.isArray(roles) ? roles : [roles];\n const mode = options?.mode ?? 'any';\n\n const hasRole = mode === 'any'\n ? auth.hasAnyRole(roleArray)\n : auth.hasAllRoles(roleArray);\n\n if (!hasRole) {\n throw new Error(options?.errorMessage ?? 'Insufficient permissions');\n }\n\n return auth;\n}\n","/**\n * @zh 房间认证 Mixin\n * @en Room authentication mixin\n */\n\nimport type { Room, Player } from '../../room/index.js';\nimport type { IAuthContext, AuthRoomConfig } from '../types.js';\nimport { getAuthContext } from './withAuth.js';\nimport { createGuestContext } from '../context.js';\n\n/**\n * @zh 带认证的玩家\n * @en Player with authentication\n */\nexport interface AuthPlayer<TUser = unknown, TData = Record<string, unknown>> extends Player<TData> {\n /**\n * @zh 认证上下文\n * @en Authentication context\n */\n readonly auth: IAuthContext<TUser>;\n\n /**\n * @zh 用户信息(快捷访问)\n * @en User info (shortcut)\n */\n readonly user: TUser | null;\n}\n\n/**\n * @zh 带认证的房间接口\n * @en Room with authentication interface\n */\nexport interface IAuthRoom<TUser = unknown> {\n /**\n * @zh 认证钩子(在 onJoin 之前调用)\n * @en Auth hook (called before onJoin)\n */\n onAuth?(player: AuthPlayer<TUser>): boolean | Promise<boolean>;\n\n /**\n * @zh 获取带认证信息的玩家\n * @en Get player with auth info\n */\n getAuthPlayer(id: string): AuthPlayer<TUser> | undefined;\n\n /**\n * @zh 获取所有带认证信息的玩家\n * @en Get all players with auth info\n */\n getAuthPlayers(): AuthPlayer<TUser>[];\n\n /**\n * @zh 按角色获取玩家\n * @en Get players by role\n */\n getPlayersByRole(role: string): AuthPlayer<TUser>[];\n\n /**\n * @zh 按用户 ID 获取玩家\n * @en Get player by user ID\n */\n getPlayerByUserId(userId: string): AuthPlayer<TUser> | undefined;\n}\n\n/**\n * @zh 认证房间构造器类型\n * @en Auth room constructor type\n */\nexport type AuthRoomClass<TUser = unknown> = new (...args: any[]) => Room & IAuthRoom<TUser>;\n\n/**\n * @zh 玩家认证上下文存储\n * @en Player auth context storage\n */\nconst playerAuthContexts = new WeakMap<Player, IAuthContext<unknown>>();\n\n/**\n * @zh 包装玩家对象添加认证信息\n * @en Wrap player object with auth info\n */\nfunction wrapPlayerWithAuth<TUser>(player: Player, authContext: IAuthContext<TUser>): AuthPlayer<TUser> {\n playerAuthContexts.set(player, authContext);\n\n Object.defineProperty(player, 'auth', {\n get: () => playerAuthContexts.get(player) ?? createGuestContext<TUser>(),\n enumerable: true,\n configurable: false\n });\n\n Object.defineProperty(player, 'user', {\n get: () => (playerAuthContexts.get(player) as IAuthContext<TUser> | undefined)?.user ?? null,\n enumerable: true,\n configurable: false\n });\n\n return player as AuthPlayer<TUser>;\n}\n\n/**\n * @zh 包装房间类添加认证功能\n * @en Wrap room class with authentication functionality\n *\n * @zh 使用 mixin 模式为房间添加认证检查,在玩家加入前验证认证状态\n * @en Uses mixin pattern to add auth checks to room, validates auth before player joins\n *\n * @example\n * ```typescript\n * import { Room, onMessage } from '@esengine/server';\n * import { withRoomAuth, type AuthPlayer } from '@esengine/server/auth';\n *\n * interface User {\n * id: string;\n * name: string;\n * roles: string[];\n * }\n *\n * class GameRoom extends withRoomAuth<User>(Room, {\n * requireAuth: true,\n * allowedRoles: ['player', 'premium'],\n * }) {\n * onJoin(player: AuthPlayer<User>) {\n * console.log(`${player.user?.name} joined the game`);\n * this.broadcast('PlayerJoined', {\n * id: player.id,\n * name: player.user?.name\n * });\n * }\n *\n * // Optional: custom auth validation\n * async onAuth(player: AuthPlayer<User>): Promise<boolean> {\n * // Additional validation logic\n * if (player.auth.hasRole('banned')) {\n * return false;\n * }\n * return true;\n * }\n *\n * @onMessage('Chat')\n * handleChat(data: { text: string }, player: AuthPlayer<User>) {\n * this.broadcast('Chat', {\n * from: player.user?.name ?? 'Guest',\n * text: data.text\n * });\n * }\n * }\n * ```\n */\nexport function withRoomAuth<TUser = unknown, TBase extends new (...args: any[]) => Room = new (...args: any[]) => Room>(\n Base: TBase,\n config: AuthRoomConfig = {}\n): TBase & (new (...args: any[]) => IAuthRoom<TUser>) {\n const {\n requireAuth = true,\n allowedRoles = [],\n roleCheckMode = 'any'\n } = config;\n\n abstract class AuthRoom extends (Base as new (...args: any[]) => Room) implements IAuthRoom<TUser> {\n private _originalOnJoin: ((player: Player) => void | Promise<void>) | undefined;\n\n constructor(...args: any[]) {\n super(...args);\n this._originalOnJoin = this.onJoin?.bind(this);\n this.onJoin = this._authOnJoin.bind(this);\n }\n\n /**\n * @zh 认证钩子(可覆盖)\n * @en Auth hook (can be overridden)\n */\n onAuth?(player: AuthPlayer<TUser>): boolean | Promise<boolean>;\n\n /**\n * @zh 包装的 onJoin 方法\n * @en Wrapped onJoin method\n */\n private async _authOnJoin(player: Player): Promise<void> {\n const conn = (player as any).connection ?? (player as any)._conn;\n const authContext = conn\n ? (getAuthContext<TUser>(conn) ?? createGuestContext<TUser>())\n : createGuestContext<TUser>();\n\n if (requireAuth && !authContext.isAuthenticated) {\n console.warn(`[AuthRoom] Rejected unauthenticated player: ${player.id}`);\n this.kick(player as any, 'Authentication required');\n return;\n }\n\n if (allowedRoles.length > 0) {\n const hasRole = roleCheckMode === 'any'\n ? authContext.hasAnyRole(allowedRoles)\n : authContext.hasAllRoles(allowedRoles);\n\n if (!hasRole) {\n console.warn(`[AuthRoom] Rejected player ${player.id}: insufficient roles`);\n this.kick(player as any, 'Insufficient permissions');\n return;\n }\n }\n\n const authPlayer = wrapPlayerWithAuth<TUser>(player, authContext);\n\n if (typeof this.onAuth === 'function') {\n try {\n const allowed = await this.onAuth(authPlayer);\n if (!allowed) {\n console.warn(`[AuthRoom] Rejected player ${player.id}: onAuth returned false`);\n this.kick(player as any, 'Authentication rejected');\n return;\n }\n } catch (error) {\n console.error(`[AuthRoom] Error in onAuth for player ${player.id}:`, error);\n this.kick(player as any, 'Authentication error');\n return;\n }\n }\n\n if (this._originalOnJoin) {\n await this._originalOnJoin(authPlayer as unknown as Player);\n }\n }\n\n /**\n * @zh 获取带认证信息的玩家\n * @en Get player with auth info\n */\n getAuthPlayer(id: string): AuthPlayer<TUser> | undefined {\n const player = this.getPlayer(id);\n return player as AuthPlayer<TUser> | undefined;\n }\n\n /**\n * @zh 获取所有带认证信息的玩家\n * @en Get all players with auth info\n */\n getAuthPlayers(): AuthPlayer<TUser>[] {\n return this.players as AuthPlayer<TUser>[];\n }\n\n /**\n * @zh 按角色获取玩家\n * @en Get players by role\n */\n getPlayersByRole(role: string): AuthPlayer<TUser>[] {\n return this.getAuthPlayers().filter(p => p.auth?.hasRole(role));\n }\n\n /**\n * @zh 按用户 ID 获取玩家\n * @en Get player by user ID\n */\n getPlayerByUserId(userId: string): AuthPlayer<TUser> | undefined {\n return this.getAuthPlayers().find(p => p.auth?.userId === userId);\n }\n }\n\n return AuthRoom as unknown as TBase & (new (...args: any[]) => IAuthRoom<TUser>);\n}\n\n/**\n * @zh 抽象认证房间基类\n * @en Abstract auth room base class\n *\n * @zh 如果不想使用 mixin,可以直接继承此类\n * @en If you don't want to use mixin, you can extend this class directly\n *\n * @example\n * ```typescript\n * import { AuthRoomBase } from '@esengine/server/auth';\n *\n * class GameRoom extends AuthRoomBase<User> {\n * protected readonly authConfig = {\n * requireAuth: true,\n * allowedRoles: ['player']\n * };\n *\n * onJoin(player: AuthPlayer<User>) {\n * // player has .auth and .user properties\n * }\n * }\n * ```\n */\nexport abstract class AuthRoomBase<TUser = unknown, TState = any, TPlayerData = Record<string, unknown>>\n implements IAuthRoom<TUser> {\n\n /**\n * @zh 认证配置(子类可覆盖)\n * @en Auth config (can be overridden by subclass)\n */\n protected readonly authConfig: AuthRoomConfig = {\n requireAuth: true,\n allowedRoles: [],\n roleCheckMode: 'any'\n };\n\n /**\n * @zh 认证钩子\n * @en Auth hook\n */\n onAuth?(player: AuthPlayer<TUser>): boolean | Promise<boolean>;\n\n getAuthPlayer(id: string): AuthPlayer<TUser> | undefined {\n return undefined;\n }\n\n getAuthPlayers(): AuthPlayer<TUser>[] {\n return [];\n }\n\n getPlayersByRole(role: string): AuthPlayer<TUser>[] {\n return [];\n }\n\n getPlayerByUserId(userId: string): AuthPlayer<TUser> | undefined {\n return undefined;\n }\n}\n","/**\n * @zh requireAuth 装饰器\n * @en requireAuth decorator\n */\n\nimport type { RequireAuthOptions } from '../types.js';\n\n/**\n * @zh 认证元数据键\n * @en Auth metadata key\n */\nexport const AUTH_METADATA_KEY = Symbol('authMetadata');\n\n/**\n * @zh 认证元数据\n * @en Auth metadata\n */\nexport interface AuthMetadata {\n requireAuth: boolean;\n options?: RequireAuthOptions;\n roles?: string[];\n roleMode?: 'any' | 'all';\n}\n\n/**\n * @zh 获取方法的认证元数据\n * @en Get auth metadata for method\n */\nexport function getAuthMetadata(target: any, propertyKey: string): AuthMetadata | undefined {\n const metadata = target[AUTH_METADATA_KEY] as Map<string, AuthMetadata> | undefined;\n return metadata?.get(propertyKey);\n}\n\n/**\n * @zh 设置方法的认证元数据\n * @en Set auth metadata for method\n */\nfunction setAuthMetadata(target: any, propertyKey: string, metadata: AuthMetadata): void {\n if (!target[AUTH_METADATA_KEY]) {\n target[AUTH_METADATA_KEY] = new Map<string, AuthMetadata>();\n }\n (target[AUTH_METADATA_KEY] as Map<string, AuthMetadata>).set(propertyKey, metadata);\n}\n\n/**\n * @zh 要求认证装饰器\n * @en Require authentication decorator\n *\n * @zh 标记方法需要认证才能访问,用于消息处理器\n * @en Marks method as requiring authentication, used for message handlers\n *\n * @example\n * ```typescript\n * class GameRoom extends withRoomAuth(Room) {\n * @requireAuth()\n * @onMessage('Trade')\n * handleTrade(data: TradeData, player: AuthPlayer) {\n * // Only authenticated players can trade\n * }\n *\n * @requireAuth({ allowGuest: true })\n * @onMessage('Chat')\n * handleChat(data: ChatData, player: AuthPlayer) {\n * // Guests can also chat\n * }\n * }\n * ```\n */\nexport function requireAuth(options?: RequireAuthOptions): MethodDecorator {\n return function (\n target: any,\n propertyKey: string | symbol,\n descriptor: PropertyDescriptor\n ) {\n const key = String(propertyKey);\n const existing = getAuthMetadata(target, key);\n\n setAuthMetadata(target, key, {\n ...existing,\n requireAuth: true,\n options\n });\n\n return descriptor;\n };\n}\n","/**\n * @zh requireRole 装饰器\n * @en requireRole decorator\n */\n\nimport type { RequireRoleOptions } from '../types.js';\nimport { AUTH_METADATA_KEY, getAuthMetadata, type AuthMetadata } from './requireAuth.js';\n\n/**\n * @zh 设置方法的认证元数据\n * @en Set auth metadata for method\n */\nfunction setAuthMetadata(target: any, propertyKey: string, metadata: AuthMetadata): void {\n if (!target[AUTH_METADATA_KEY]) {\n target[AUTH_METADATA_KEY] = new Map<string, AuthMetadata>();\n }\n (target[AUTH_METADATA_KEY] as Map<string, AuthMetadata>).set(propertyKey, metadata);\n}\n\n/**\n * @zh 要求角色装饰器\n * @en Require role decorator\n *\n * @zh 标记方法需要特定角色才能访问\n * @en Marks method as requiring specific role(s)\n *\n * @example\n * ```typescript\n * class AdminRoom extends withRoomAuth(Room) {\n * @requireRole('admin')\n * @onMessage('Ban')\n * handleBan(data: BanData, player: AuthPlayer) {\n * // Only admins can ban\n * }\n *\n * @requireRole(['moderator', 'admin'])\n * @onMessage('Mute')\n * handleMute(data: MuteData, player: AuthPlayer) {\n * // Moderators or admins can mute\n * }\n *\n * @requireRole(['verified', 'premium'], { mode: 'all' })\n * @onMessage('SpecialFeature')\n * handleSpecial(data: any, player: AuthPlayer) {\n * // Requires both verified AND premium roles\n * }\n * }\n * ```\n */\nexport function requireRole(\n roles: string | string[],\n options?: RequireRoleOptions\n): MethodDecorator {\n return function (\n target: any,\n propertyKey: string | symbol,\n descriptor: PropertyDescriptor\n ) {\n const key = String(propertyKey);\n const existing = getAuthMetadata(target, key);\n const roleArray = Array.isArray(roles) ? roles : [roles];\n\n setAuthMetadata(target, key, {\n ...existing,\n requireAuth: true,\n roles: roleArray,\n roleMode: options?.mode ?? 'any',\n options\n });\n\n return descriptor;\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/auth/context.ts","../../src/auth/providers/JwtAuthProvider.ts","../../src/auth/providers/SessionAuthProvider.ts","../../src/auth/mixin/withAuth.ts","../../src/auth/mixin/withRoomAuth.ts","../../src/auth/decorators/requireAuth.ts","../../src/auth/decorators/requireRole.ts"],"names":["defaultUserExtractor","getId","user","u","id","String","userId","sub","getRoles","Array","isArray","roles","filter","r","role","AuthContext","extractor","_isAuthenticated","_user","_userId","_roles","_authenticatedAt","_expiresAt","_extractor","isAuthenticated","Date","now","authenticatedAt","expiresAt","hasRole","includes","hasAnyRole","some","hasAllRoles","every","setAuthenticated","result","success","clear","createGuestContext","createAuthContext","context","JwtAuthProvider","config","name","_config","algorithm","expiresIn","verify","token","error","errorCode","verifyOptions","algorithms","issuer","audience","payload","secret","getUser","exp","undefined","err","message","refresh","decode","iat","nbf","restPayload","newToken","sign","signOptions","createJwtAuthProvider","SessionAuthProvider","sessionTTL","prefix","autoRenew","_getKey","sessionId","key","session","storage","get","validateUser","isValid","lastActiveAt","set","createdAt","revoke","delete","createSession","data","_generateSessionId","getSession","updateSession","randomBytes","toString","createSessionAuthProvider","logger","createLogger","AUTH_CONTEXT_KEY","getAuthContext","conn","setAuthContext","withAuth","server","provider","extractCredentials","autoAuthOnConnect","disconnectOnAuthFailure","onAuthSuccess","onAuthFailure","originalConnections","connections","connectionAuthMap","WeakMap","authServer","authProvider","authenticate","credentials","authContext","originalOnConnect","_onConnect","req","connReq","close","originalOnDisconnect","_onDisconnect","requireAuthentication","options","auth","Error","errorMessage","requireRole","roleArray","mode","playerAuthContexts","wrapPlayerWithAuth","player","Object","defineProperty","enumerable","configurable","withRoomAuth","Base","requireAuth","allowedRoles","roleCheckMode","AuthRoom","args","_originalOnJoin","onJoin","bind","_authOnJoin","connection","_conn","warn","kick","length","authPlayer","onAuth","allowed","getAuthPlayer","getPlayer","getAuthPlayers","players","getPlayersByRole","p","getPlayerByUserId","find","AuthRoomBase","authConfig","AUTH_METADATA_KEY","getAuthMetadata","target","propertyKey","metadata","setAuthMetadata","Map","descriptor","existing","roleMode"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @zh 认证上下文实现\n * @en Authentication context implementation\n */\n\nimport type { IAuthContext, AuthResult } from './types.js';\n\n/**\n * @zh 用户信息提取器\n * @en User info extractor\n */\nexport interface UserInfoExtractor<TUser> {\n /**\n * @zh 提取用户 ID\n * @en Extract user ID\n */\n getId(user: TUser): string;\n\n /**\n * @zh 提取用户角色\n * @en Extract user roles\n */\n getRoles(user: TUser): string[];\n}\n\n/**\n * @zh 默认用户信息提取器\n * @en Default user info extractor\n */\nexport const defaultUserExtractor: UserInfoExtractor<unknown> = {\n getId(user: unknown): string {\n if (user && typeof user === 'object') {\n const u = user as Record<string, unknown>;\n if (typeof u.id === 'string') return u.id;\n if (typeof u.id === 'number') return String(u.id);\n if (typeof u.userId === 'string') return u.userId;\n if (typeof u.userId === 'number') return String(u.userId);\n if (typeof u.sub === 'string') return u.sub;\n }\n return '';\n },\n\n getRoles(user: unknown): string[] {\n if (user && typeof user === 'object') {\n const u = user as Record<string, unknown>;\n if (Array.isArray(u.roles)) {\n return u.roles.filter((r): r is string => typeof r === 'string');\n }\n if (typeof u.role === 'string') {\n return [u.role];\n }\n }\n return [];\n }\n};\n\n/**\n * @zh 认证上下文\n * @en Authentication context\n *\n * @zh 存储连接的认证状态\n * @en Stores authentication state for a connection\n */\nexport class AuthContext<TUser = unknown> implements IAuthContext<TUser> {\n private _isAuthenticated: boolean = false;\n private _user: TUser | null = null;\n private _userId: string | null = null;\n private _roles: string[] = [];\n private _authenticatedAt: number | null = null;\n private _expiresAt: number | null = null;\n private _extractor: UserInfoExtractor<TUser>;\n\n constructor(extractor?: UserInfoExtractor<TUser>) {\n this._extractor = (extractor ?? defaultUserExtractor) as UserInfoExtractor<TUser>;\n }\n\n /**\n * @zh 是否已认证\n * @en Whether authenticated\n */\n get isAuthenticated(): boolean {\n if (this._expiresAt && Date.now() > this._expiresAt) {\n return false;\n }\n return this._isAuthenticated;\n }\n\n /**\n * @zh 用户信息\n * @en User information\n */\n get user(): TUser | null {\n return this._user;\n }\n\n /**\n * @zh 用户 ID\n * @en User ID\n */\n get userId(): string | null {\n return this._userId;\n }\n\n /**\n * @zh 用户角色\n * @en User roles\n */\n get roles(): ReadonlyArray<string> {\n return this._roles;\n }\n\n /**\n * @zh 认证时间\n * @en Authentication timestamp\n */\n get authenticatedAt(): number | null {\n return this._authenticatedAt;\n }\n\n /**\n * @zh 令牌过期时间\n * @en Token expiration time\n */\n get expiresAt(): number | null {\n return this._expiresAt;\n }\n\n /**\n * @zh 检查是否有指定角色\n * @en Check if has specified role\n */\n hasRole(role: string): boolean {\n return this._roles.includes(role);\n }\n\n /**\n * @zh 检查是否有任一指定角色\n * @en Check if has any of specified roles\n */\n hasAnyRole(roles: string[]): boolean {\n return roles.some((role) => this._roles.includes(role));\n }\n\n /**\n * @zh 检查是否有所有指定角色\n * @en Check if has all specified roles\n */\n hasAllRoles(roles: string[]): boolean {\n return roles.every((role) => this._roles.includes(role));\n }\n\n /**\n * @zh 设置认证结果\n * @en Set authentication result\n */\n setAuthenticated(result: AuthResult<TUser>): void {\n if (result.success && result.user) {\n this._isAuthenticated = true;\n this._user = result.user;\n this._userId = this._extractor.getId(result.user);\n this._roles = this._extractor.getRoles(result.user);\n this._authenticatedAt = Date.now();\n this._expiresAt = result.expiresAt ?? null;\n } else {\n this.clear();\n }\n }\n\n /**\n * @zh 清除认证状态\n * @en Clear authentication state\n */\n clear(): void {\n this._isAuthenticated = false;\n this._user = null;\n this._userId = null;\n this._roles = [];\n this._authenticatedAt = null;\n this._expiresAt = null;\n }\n}\n\n/**\n * @zh 创建访客认证上下文\n * @en Create guest auth context\n */\nexport function createGuestContext<TUser = unknown>(): IAuthContext<TUser> {\n return new AuthContext<TUser>();\n}\n\n/**\n * @zh 从认证结果创建认证上下文\n * @en Create auth context from auth result\n */\nexport function createAuthContext<TUser = unknown>(\n result: AuthResult<TUser>,\n extractor?: UserInfoExtractor<TUser>\n): AuthContext<TUser> {\n const context = new AuthContext<TUser>(extractor);\n context.setAuthenticated(result);\n return context;\n}\n","/**\n * @zh JWT 认证提供者\n * @en JWT authentication provider\n */\n\nimport type { IAuthProvider, AuthResult, AuthErrorCode } from '../types.js';\nimport * as jwt from 'jsonwebtoken';\n\n/**\n * @zh JWT 载荷\n * @en JWT payload\n */\nexport interface JwtPayload {\n /**\n * @zh 主题(用户 ID)\n * @en Subject (user ID)\n */\n sub?: string;\n\n /**\n * @zh 签发时间\n * @en Issued at\n */\n iat?: number;\n\n /**\n * @zh 过期时间\n * @en Expiration time\n */\n exp?: number;\n\n /**\n * @zh 自定义字段\n * @en Custom fields\n */\n [key: string]: unknown;\n}\n\n/**\n * @zh JWT 认证配置\n * @en JWT authentication configuration\n */\nexport interface JwtAuthConfig<TUser = unknown> {\n /**\n * @zh 密钥\n * @en Secret key\n */\n secret: string;\n\n /**\n * @zh 算法\n * @en Algorithm\n * @defaultValue 'HS256'\n */\n algorithm?: 'HS256' | 'HS384' | 'HS512' | 'RS256' | 'RS384' | 'RS512';\n\n /**\n * @zh 令牌过期时间(秒)\n * @en Token expiration in seconds\n * @defaultValue 3600\n */\n expiresIn?: number;\n\n /**\n * @zh 从载荷获取用户信息\n * @en Get user from payload\n */\n getUser?: (payload: JwtPayload) => TUser | Promise<TUser | null> | null;\n\n /**\n * @zh 签发者\n * @en Issuer\n */\n issuer?: string;\n\n /**\n * @zh 受众\n * @en Audience\n */\n audience?: string;\n}\n\n/**\n * @zh JWT 认证提供者\n * @en JWT authentication provider\n *\n * @zh 使用 jsonwebtoken 库实现 JWT 认证\n * @en Uses jsonwebtoken library for JWT authentication\n *\n * @example\n * ```typescript\n * const jwtProvider = createJwtAuthProvider({\n * secret: 'your-secret-key',\n * expiresIn: 3600,\n * getUser: async (payload) => {\n * return await db.users.findById(payload.sub);\n * }\n * });\n * ```\n */\nexport class JwtAuthProvider<TUser = unknown> implements IAuthProvider<TUser, string> {\n readonly name = 'jwt';\n\n private _config: Required<Pick<JwtAuthConfig<TUser>, 'secret' | 'algorithm' | 'expiresIn'>> & JwtAuthConfig<TUser>;\n\n constructor(config: JwtAuthConfig<TUser>) {\n this._config = {\n algorithm: 'HS256',\n expiresIn: 3600,\n ...config\n };\n }\n\n /**\n * @zh 验证令牌\n * @en Verify token\n */\n async verify(token: string): Promise<AuthResult<TUser>> {\n if (!token) {\n return {\n success: false,\n error: 'Token is required',\n errorCode: 'INVALID_TOKEN'\n };\n }\n\n try {\n const verifyOptions: jwt.VerifyOptions = {\n algorithms: [this._config.algorithm]\n };\n if (this._config.issuer) {\n verifyOptions.issuer = this._config.issuer;\n }\n if (this._config.audience) {\n verifyOptions.audience = this._config.audience;\n }\n const payload = jwt.verify(token, this._config.secret, verifyOptions) as JwtPayload;\n\n let user: TUser | null = null;\n\n if (this._config.getUser) {\n user = await this._config.getUser(payload);\n if (!user) {\n return {\n success: false,\n error: 'User not found',\n errorCode: 'USER_NOT_FOUND'\n };\n }\n } else {\n user = payload as unknown as TUser;\n }\n\n return {\n success: true,\n user,\n token,\n expiresAt: payload.exp ? payload.exp * 1000 : undefined\n };\n } catch (error) {\n const err = error as Error;\n\n if (err.name === 'TokenExpiredError') {\n return {\n success: false,\n error: 'Token has expired',\n errorCode: 'EXPIRED_TOKEN'\n };\n }\n\n return {\n success: false,\n error: err.message || 'Invalid token',\n errorCode: 'INVALID_TOKEN'\n };\n }\n }\n\n /**\n * @zh 刷新令牌\n * @en Refresh token\n */\n async refresh(token: string): Promise<AuthResult<TUser>> {\n const result = await this.verify(token);\n\n if (!result.success || !result.user) {\n return result;\n }\n\n const payload = jwt.decode(token) as JwtPayload;\n\n // Remove JWT standard claims that will be regenerated\n const { iat, exp, nbf, ...restPayload } = payload;\n\n const newToken = this.sign(restPayload);\n\n return {\n success: true,\n user: result.user,\n token: newToken,\n expiresAt: Date.now() + this._config.expiresIn * 1000\n };\n }\n\n /**\n * @zh 生成令牌\n * @en Generate token\n */\n sign(payload: Record<string, unknown>): string {\n const signOptions: jwt.SignOptions = {\n algorithm: this._config.algorithm,\n expiresIn: this._config.expiresIn\n };\n if (this._config.issuer) {\n signOptions.issuer = this._config.issuer;\n }\n if (this._config.audience) {\n signOptions.audience = this._config.audience;\n }\n return jwt.sign(payload, this._config.secret, signOptions);\n }\n\n /**\n * @zh 解码令牌(不验证)\n * @en Decode token (without verification)\n */\n decode(token: string): JwtPayload | null {\n return jwt.decode(token) as JwtPayload | null;\n }\n}\n\n/**\n * @zh 创建 JWT 认证提供者\n * @en Create JWT authentication provider\n *\n * @example\n * ```typescript\n * import { createJwtAuthProvider } from '@esengine/server/auth';\n *\n * const jwtProvider = createJwtAuthProvider({\n * secret: process.env.JWT_SECRET!,\n * expiresIn: 3600,\n * getUser: async (payload) => {\n * return { id: payload.sub, name: payload.name };\n * }\n * });\n * ```\n */\nexport function createJwtAuthProvider<TUser = unknown>(\n config: JwtAuthConfig<TUser>\n): JwtAuthProvider<TUser> {\n return new JwtAuthProvider<TUser>(config);\n}\n","/**\n * @zh Session 认证提供者\n * @en Session authentication provider\n */\n\nimport { randomBytes } from 'crypto';\nimport type { IAuthProvider, AuthResult } from '../types.js';\n\n/**\n * @zh Session 存储接口(兼容 ITransactionStorage)\n * @en Session storage interface (compatible with ITransactionStorage)\n */\nexport interface ISessionStorage {\n get<T>(key: string): Promise<T | null>;\n set<T>(key: string, value: T, ttl?: number): Promise<void>;\n delete(key: string): Promise<boolean>;\n}\n\n/**\n * @zh Session 数据\n * @en Session data\n */\nexport interface SessionData<TUser = unknown> {\n /**\n * @zh 用户信息\n * @en User information\n */\n user: TUser;\n\n /**\n * @zh 创建时间\n * @en Created at\n */\n createdAt: number;\n\n /**\n * @zh 最后活跃时间\n * @en Last active at\n */\n lastActiveAt: number;\n\n /**\n * @zh 自定义数据\n * @en Custom data\n */\n data?: Record<string, unknown>;\n}\n\n/**\n * @zh Session 认证配置\n * @en Session authentication configuration\n */\nexport interface SessionAuthConfig<TUser = unknown> {\n /**\n * @zh Session 存储\n * @en Session storage\n */\n storage: ISessionStorage;\n\n /**\n * @zh Session 过期时间(毫秒)\n * @en Session expiration in milliseconds\n * @defaultValue 86400000 (24h)\n */\n sessionTTL?: number;\n\n /**\n * @zh Session 键前缀\n * @en Session key prefix\n * @defaultValue 'session:'\n */\n prefix?: string;\n\n /**\n * @zh 验证用户(可选额外验证)\n * @en Validate user (optional extra validation)\n */\n validateUser?: (user: TUser) => boolean | Promise<boolean>;\n\n /**\n * @zh 是否自动续期\n * @en Auto renew session\n * @defaultValue true\n */\n autoRenew?: boolean;\n}\n\n/**\n * @zh Session 认证提供者\n * @en Session authentication provider\n *\n * @zh 基于存储的会话认证,支持 Redis、MongoDB 等后端\n * @en Storage-based session authentication, supports Redis, MongoDB, etc.\n *\n * @example\n * ```typescript\n * import { createSessionAuthProvider } from '@esengine/server/auth';\n * import { createRedisStorage } from '@esengine/transaction';\n *\n * const sessionProvider = createSessionAuthProvider({\n * storage: createRedisStorage({ factory: () => new Redis() }),\n * sessionTTL: 86400000, // 24 hours\n * });\n * ```\n */\nexport class SessionAuthProvider<TUser = unknown> implements IAuthProvider<TUser, string> {\n readonly name = 'session';\n\n private _config: Required<Pick<SessionAuthConfig<TUser>, 'sessionTTL' | 'prefix' | 'autoRenew'>> & SessionAuthConfig<TUser>;\n\n constructor(config: SessionAuthConfig<TUser>) {\n this._config = {\n sessionTTL: 86400000,\n prefix: 'session:',\n autoRenew: true,\n ...config\n };\n }\n\n /**\n * @zh 获取存储键\n * @en Get storage key\n */\n private _getKey(sessionId: string): string {\n return `${this._config.prefix}${sessionId}`;\n }\n\n /**\n * @zh 验证 Session\n * @en Verify session\n */\n async verify(sessionId: string): Promise<AuthResult<TUser>> {\n if (!sessionId) {\n return {\n success: false,\n error: 'Session ID is required',\n errorCode: 'INVALID_TOKEN'\n };\n }\n\n const key = this._getKey(sessionId);\n const session = await this._config.storage.get<SessionData<TUser>>(key);\n\n if (!session) {\n return {\n success: false,\n error: 'Session not found or expired',\n errorCode: 'EXPIRED_TOKEN'\n };\n }\n\n if (this._config.validateUser) {\n const isValid = await this._config.validateUser(session.user);\n if (!isValid) {\n return {\n success: false,\n error: 'User validation failed',\n errorCode: 'ACCOUNT_DISABLED'\n };\n }\n }\n\n if (this._config.autoRenew) {\n session.lastActiveAt = Date.now();\n await this._config.storage.set(key, session, this._config.sessionTTL);\n }\n\n return {\n success: true,\n user: session.user,\n token: sessionId,\n expiresAt: session.createdAt + this._config.sessionTTL\n };\n }\n\n /**\n * @zh 刷新 Session\n * @en Refresh session\n */\n async refresh(sessionId: string): Promise<AuthResult<TUser>> {\n const result = await this.verify(sessionId);\n\n if (!result.success) {\n return result;\n }\n\n const key = this._getKey(sessionId);\n const session = await this._config.storage.get<SessionData<TUser>>(key);\n\n if (session) {\n session.lastActiveAt = Date.now();\n await this._config.storage.set(key, session, this._config.sessionTTL);\n }\n\n return {\n ...result,\n expiresAt: Date.now() + this._config.sessionTTL\n };\n }\n\n /**\n * @zh 撤销 Session\n * @en Revoke session\n */\n async revoke(sessionId: string): Promise<boolean> {\n const key = this._getKey(sessionId);\n return await this._config.storage.delete(key);\n }\n\n /**\n * @zh 创建 Session\n * @en Create session\n */\n async createSession(user: TUser, data?: Record<string, unknown>): Promise<string> {\n const sessionId = this._generateSessionId();\n const key = this._getKey(sessionId);\n\n const session: SessionData<TUser> = {\n user,\n createdAt: Date.now(),\n lastActiveAt: Date.now(),\n data\n };\n\n await this._config.storage.set(key, session, this._config.sessionTTL);\n\n return sessionId;\n }\n\n /**\n * @zh 获取 Session 数据\n * @en Get session data\n */\n async getSession(sessionId: string): Promise<SessionData<TUser> | null> {\n const key = this._getKey(sessionId);\n return await this._config.storage.get<SessionData<TUser>>(key);\n }\n\n /**\n * @zh 更新 Session 数据\n * @en Update session data\n */\n async updateSession(sessionId: string, data: Record<string, unknown>): Promise<boolean> {\n const key = this._getKey(sessionId);\n const session = await this._config.storage.get<SessionData<TUser>>(key);\n\n if (!session) {\n return false;\n }\n\n session.data = { ...session.data, ...data };\n session.lastActiveAt = Date.now();\n await this._config.storage.set(key, session, this._config.sessionTTL);\n\n return true;\n }\n\n /**\n * @zh 生成 Session ID(使用加密安全的随机数)\n * @en Generate session ID (using cryptographically secure random)\n */\n private _generateSessionId(): string {\n return randomBytes(32).toString('hex');\n }\n}\n\n/**\n * @zh 创建 Session 认证提供者\n * @en Create session authentication provider\n *\n * @example\n * ```typescript\n * import { createSessionAuthProvider } from '@esengine/server/auth';\n * import { MemoryStorage } from '@esengine/transaction';\n *\n * const sessionProvider = createSessionAuthProvider({\n * storage: new MemoryStorage(),\n * sessionTTL: 3600000, // 1 hour\n * });\n *\n * // Create a session\n * const sessionId = await sessionProvider.createSession({ id: '1', name: 'Alice' });\n *\n * // Verify session\n * const result = await sessionProvider.verify(sessionId);\n * ```\n */\nexport function createSessionAuthProvider<TUser = unknown>(\n config: SessionAuthConfig<TUser>\n): SessionAuthProvider<TUser> {\n return new SessionAuthProvider<TUser>(config);\n}\n","/**\n * @zh 服务器认证 Mixin\n * @en Server authentication mixin\n */\n\nimport type { ServerConnection, GameServer } from '../../types/index.js';\nimport { createLogger } from '../../logger.js';\nimport type {\n IAuthProvider,\n AuthResult,\n AuthServerConfig,\n AuthGameServer,\n IAuthContext,\n ConnectionRequest\n} from '../types.js';\nimport { AuthContext } from '../context.js';\n\nconst logger = createLogger('Auth');\n\n/**\n * @zh 认证数据键\n * @en Auth data key\n */\nconst AUTH_CONTEXT_KEY = Symbol('authContext');\n\n/**\n * @zh 获取连接的认证上下文\n * @en Get auth context for connection\n */\nexport function getAuthContext<TUser = unknown>(conn: ServerConnection): IAuthContext<TUser> | null {\n const data = conn.data as Record<symbol, unknown>;\n return (data[AUTH_CONTEXT_KEY] as IAuthContext<TUser>) ?? null;\n}\n\n/**\n * @zh 设置连接的认证上下文\n * @en Set auth context for connection\n */\nexport function setAuthContext<TUser = unknown>(conn: ServerConnection, context: IAuthContext<TUser>): void {\n const data = conn.data as Record<symbol, unknown>;\n data[AUTH_CONTEXT_KEY] = context;\n}\n\n/**\n * @zh 包装服务器添加认证功能\n * @en Wrap server with authentication functionality\n *\n * @zh 使用 mixin 模式为服务器添加认证能力,不修改原始服务器\n * @en Uses mixin pattern to add authentication to server without modifying original\n *\n * @example\n * ```typescript\n * import { createServer } from '@esengine/server';\n * import { withAuth, createJwtAuthProvider } from '@esengine/server/auth';\n *\n * const jwtProvider = createJwtAuthProvider({\n * secret: 'your-secret-key',\n * expiresIn: 3600,\n * });\n *\n * const server = withAuth(await createServer({ port: 3000 }), {\n * provider: jwtProvider,\n * extractCredentials: (req) => {\n * const url = new URL(req.url, 'http://localhost');\n * return url.searchParams.get('token');\n * },\n * onAuthSuccess: (conn, user) => {\n * console.log(`User ${user.name} authenticated`);\n * },\n * onAuthFailure: (conn, error) => {\n * console.log(`Auth failed: ${error.error}`);\n * }\n * });\n *\n * await server.start();\n * ```\n */\nexport function withAuth<TUser = unknown>(\n server: GameServer,\n config: AuthServerConfig<TUser>\n): AuthGameServer<TUser> {\n const {\n provider,\n extractCredentials,\n autoAuthOnConnect = true,\n disconnectOnAuthFailure = false,\n onAuthSuccess,\n onAuthFailure\n } = config;\n\n const originalConnections = server.connections;\n const connectionAuthMap = new WeakMap<ServerConnection, AuthContext<TUser>>();\n\n const authServer: AuthGameServer<TUser> = {\n ...server,\n\n get authProvider(): IAuthProvider<TUser> {\n return provider;\n },\n\n async authenticate(\n conn: ServerConnection,\n credentials: unknown\n ): Promise<AuthResult<TUser>> {\n const result = await provider.verify(credentials as never);\n\n let authContext = connectionAuthMap.get(conn);\n if (!authContext) {\n authContext = new AuthContext<TUser>();\n connectionAuthMap.set(conn, authContext);\n setAuthContext(conn, authContext);\n }\n\n if (result.success) {\n authContext.setAuthenticated(result);\n await onAuthSuccess?.(conn, result.user!);\n } else {\n authContext.clear();\n await onAuthFailure?.(conn, result);\n }\n\n return result;\n },\n\n getAuthContext(conn: ServerConnection): IAuthContext<TUser> | null {\n return connectionAuthMap.get(conn) ?? null;\n },\n\n get connections(): ReadonlyArray<ServerConnection> {\n return originalConnections;\n }\n };\n\n const originalOnConnect = (server as any)._onConnect;\n (server as any)._onConnect = async (conn: ServerConnection, req?: unknown) => {\n const authContext = new AuthContext<TUser>();\n connectionAuthMap.set(conn, authContext);\n setAuthContext(conn, authContext);\n\n if (autoAuthOnConnect && extractCredentials && req) {\n try {\n const connReq = req as ConnectionRequest;\n const credentials = await extractCredentials(connReq);\n\n if (credentials) {\n const result = await provider.verify(credentials as never);\n\n if (result.success) {\n authContext.setAuthenticated(result);\n await onAuthSuccess?.(conn, result.user!);\n } else {\n await onAuthFailure?.(conn, result);\n\n if (disconnectOnAuthFailure) {\n (conn as any).close?.();\n return;\n }\n }\n }\n } catch (error) {\n logger.error('Error during auto-authentication:', error);\n }\n }\n\n if (originalOnConnect) {\n await originalOnConnect(conn, req);\n }\n };\n\n const originalOnDisconnect = (server as any)._onDisconnect;\n (server as any)._onDisconnect = async (conn: ServerConnection) => {\n connectionAuthMap.delete(conn);\n\n if (originalOnDisconnect) {\n await originalOnDisconnect(conn);\n }\n };\n\n return authServer;\n}\n\n/**\n * @zh 创建认证中间件\n * @en Create authentication middleware\n *\n * @zh 用于在 API 处理器中检查认证状态\n * @en Used to check authentication status in API handlers\n */\nexport function requireAuthentication<TUser = unknown>(\n conn: ServerConnection,\n options?: { errorMessage?: string }\n): IAuthContext<TUser> {\n const auth = getAuthContext<TUser>(conn);\n\n if (!auth || !auth.isAuthenticated) {\n throw new Error(options?.errorMessage ?? 'Authentication required');\n }\n\n return auth;\n}\n\n/**\n * @zh 创建角色检查中间件\n * @en Create role check middleware\n */\nexport function requireRole<TUser = unknown>(\n conn: ServerConnection,\n roles: string | string[],\n options?: { mode?: 'any' | 'all'; errorMessage?: string }\n): IAuthContext<TUser> {\n const auth = requireAuthentication<TUser>(conn);\n const roleArray = Array.isArray(roles) ? roles : [roles];\n const mode = options?.mode ?? 'any';\n\n const hasRole = mode === 'any'\n ? auth.hasAnyRole(roleArray)\n : auth.hasAllRoles(roleArray);\n\n if (!hasRole) {\n throw new Error(options?.errorMessage ?? 'Insufficient permissions');\n }\n\n return auth;\n}\n","/**\n * @zh 房间认证 Mixin\n * @en Room authentication mixin\n */\n\nimport type { Room, Player } from '../../room/index.js';\nimport type { IAuthContext, AuthRoomConfig } from '../types.js';\nimport { createLogger } from '../../logger.js';\nimport { getAuthContext } from './withAuth.js';\nimport { createGuestContext } from '../context.js';\n\nconst logger = createLogger('AuthRoom');\n\n/**\n * @zh 带认证的玩家\n * @en Player with authentication\n */\nexport interface AuthPlayer<TUser = unknown, TData = Record<string, unknown>> extends Player<TData> {\n /**\n * @zh 认证上下文\n * @en Authentication context\n */\n readonly auth: IAuthContext<TUser>;\n\n /**\n * @zh 用户信息(快捷访问)\n * @en User info (shortcut)\n */\n readonly user: TUser | null;\n}\n\n/**\n * @zh 带认证的房间接口\n * @en Room with authentication interface\n */\nexport interface IAuthRoom<TUser = unknown> {\n /**\n * @zh 认证钩子(在 onJoin 之前调用)\n * @en Auth hook (called before onJoin)\n */\n onAuth?(player: AuthPlayer<TUser>): boolean | Promise<boolean>;\n\n /**\n * @zh 获取带认证信息的玩家\n * @en Get player with auth info\n */\n getAuthPlayer(id: string): AuthPlayer<TUser> | undefined;\n\n /**\n * @zh 获取所有带认证信息的玩家\n * @en Get all players with auth info\n */\n getAuthPlayers(): AuthPlayer<TUser>[];\n\n /**\n * @zh 按角色获取玩家\n * @en Get players by role\n */\n getPlayersByRole(role: string): AuthPlayer<TUser>[];\n\n /**\n * @zh 按用户 ID 获取玩家\n * @en Get player by user ID\n */\n getPlayerByUserId(userId: string): AuthPlayer<TUser> | undefined;\n}\n\n/**\n * @zh 认证房间构造器类型\n * @en Auth room constructor type\n */\nexport type AuthRoomClass<TUser = unknown> = new (...args: any[]) => Room & IAuthRoom<TUser>;\n\n/**\n * @zh 玩家认证上下文存储\n * @en Player auth context storage\n */\nconst playerAuthContexts = new WeakMap<Player, IAuthContext<unknown>>();\n\n/**\n * @zh 包装玩家对象添加认证信息\n * @en Wrap player object with auth info\n */\nfunction wrapPlayerWithAuth<TUser>(player: Player, authContext: IAuthContext<TUser>): AuthPlayer<TUser> {\n playerAuthContexts.set(player, authContext);\n\n Object.defineProperty(player, 'auth', {\n get: () => playerAuthContexts.get(player) ?? createGuestContext<TUser>(),\n enumerable: true,\n configurable: false\n });\n\n Object.defineProperty(player, 'user', {\n get: () => (playerAuthContexts.get(player) as IAuthContext<TUser> | undefined)?.user ?? null,\n enumerable: true,\n configurable: false\n });\n\n return player as AuthPlayer<TUser>;\n}\n\n/**\n * @zh 包装房间类添加认证功能\n * @en Wrap room class with authentication functionality\n *\n * @zh 使用 mixin 模式为房间添加认证检查,在玩家加入前验证认证状态\n * @en Uses mixin pattern to add auth checks to room, validates auth before player joins\n *\n * @example\n * ```typescript\n * import { Room, onMessage } from '@esengine/server';\n * import { withRoomAuth, type AuthPlayer } from '@esengine/server/auth';\n *\n * interface User {\n * id: string;\n * name: string;\n * roles: string[];\n * }\n *\n * class GameRoom extends withRoomAuth<User>(Room, {\n * requireAuth: true,\n * allowedRoles: ['player', 'premium'],\n * }) {\n * onJoin(player: AuthPlayer<User>) {\n * console.log(`${player.user?.name} joined the game`);\n * this.broadcast('PlayerJoined', {\n * id: player.id,\n * name: player.user?.name\n * });\n * }\n *\n * // Optional: custom auth validation\n * async onAuth(player: AuthPlayer<User>): Promise<boolean> {\n * // Additional validation logic\n * if (player.auth.hasRole('banned')) {\n * return false;\n * }\n * return true;\n * }\n *\n * @onMessage('Chat')\n * handleChat(data: { text: string }, player: AuthPlayer<User>) {\n * this.broadcast('Chat', {\n * from: player.user?.name ?? 'Guest',\n * text: data.text\n * });\n * }\n * }\n * ```\n */\nexport function withRoomAuth<TUser = unknown, TBase extends new (...args: any[]) => Room = new (...args: any[]) => Room>(\n Base: TBase,\n config: AuthRoomConfig = {}\n): TBase & (new (...args: any[]) => IAuthRoom<TUser>) {\n const {\n requireAuth = true,\n allowedRoles = [],\n roleCheckMode = 'any'\n } = config;\n\n abstract class AuthRoom extends (Base as new (...args: any[]) => Room) implements IAuthRoom<TUser> {\n private _originalOnJoin: ((player: Player) => void | Promise<void>) | undefined;\n\n constructor(...args: any[]) {\n super(...args);\n this._originalOnJoin = this.onJoin?.bind(this);\n this.onJoin = this._authOnJoin.bind(this);\n }\n\n /**\n * @zh 认证钩子(可覆盖)\n * @en Auth hook (can be overridden)\n */\n onAuth?(player: AuthPlayer<TUser>): boolean | Promise<boolean>;\n\n /**\n * @zh 包装的 onJoin 方法\n * @en Wrapped onJoin method\n */\n private async _authOnJoin(player: Player): Promise<void> {\n const conn = (player as any).connection ?? (player as any)._conn;\n const authContext = conn\n ? (getAuthContext<TUser>(conn) ?? createGuestContext<TUser>())\n : createGuestContext<TUser>();\n\n if (requireAuth && !authContext.isAuthenticated) {\n logger.warn(`Rejected unauthenticated player: ${player.id}`);\n this.kick(player as any, 'Authentication required');\n return;\n }\n\n if (allowedRoles.length > 0) {\n const hasRole = roleCheckMode === 'any'\n ? authContext.hasAnyRole(allowedRoles)\n : authContext.hasAllRoles(allowedRoles);\n\n if (!hasRole) {\n logger.warn(`Rejected player ${player.id}: insufficient roles`);\n this.kick(player as any, 'Insufficient permissions');\n return;\n }\n }\n\n const authPlayer = wrapPlayerWithAuth<TUser>(player, authContext);\n\n if (typeof this.onAuth === 'function') {\n try {\n const allowed = await this.onAuth(authPlayer);\n if (!allowed) {\n logger.warn(`Rejected player ${player.id}: onAuth returned false`);\n this.kick(player as any, 'Authentication rejected');\n return;\n }\n } catch (error) {\n logger.error(`Error in onAuth for player ${player.id}:`, error);\n this.kick(player as any, 'Authentication error');\n return;\n }\n }\n\n if (this._originalOnJoin) {\n await this._originalOnJoin(authPlayer as unknown as Player);\n }\n }\n\n /**\n * @zh 获取带认证信息的玩家\n * @en Get player with auth info\n */\n getAuthPlayer(id: string): AuthPlayer<TUser> | undefined {\n const player = this.getPlayer(id);\n return player as AuthPlayer<TUser> | undefined;\n }\n\n /**\n * @zh 获取所有带认证信息的玩家\n * @en Get all players with auth info\n */\n getAuthPlayers(): AuthPlayer<TUser>[] {\n return this.players as AuthPlayer<TUser>[];\n }\n\n /**\n * @zh 按角色获取玩家\n * @en Get players by role\n */\n getPlayersByRole(role: string): AuthPlayer<TUser>[] {\n return this.getAuthPlayers().filter((p) => p.auth?.hasRole(role));\n }\n\n /**\n * @zh 按用户 ID 获取玩家\n * @en Get player by user ID\n */\n getPlayerByUserId(userId: string): AuthPlayer<TUser> | undefined {\n return this.getAuthPlayers().find((p) => p.auth?.userId === userId);\n }\n }\n\n return AuthRoom as unknown as TBase & (new (...args: any[]) => IAuthRoom<TUser>);\n}\n\n/**\n * @zh 抽象认证房间基类\n * @en Abstract auth room base class\n *\n * @zh 如果不想使用 mixin,可以直接继承此类\n * @en If you don't want to use mixin, you can extend this class directly\n *\n * @example\n * ```typescript\n * import { AuthRoomBase } from '@esengine/server/auth';\n *\n * class GameRoom extends AuthRoomBase<User> {\n * protected readonly authConfig = {\n * requireAuth: true,\n * allowedRoles: ['player']\n * };\n *\n * onJoin(player: AuthPlayer<User>) {\n * // player has .auth and .user properties\n * }\n * }\n * ```\n */\nexport abstract class AuthRoomBase<TUser = unknown, TState = any, TPlayerData = Record<string, unknown>>\nimplements IAuthRoom<TUser> {\n\n /**\n * @zh 认证配置(子类可覆盖)\n * @en Auth config (can be overridden by subclass)\n */\n protected readonly authConfig: AuthRoomConfig = {\n requireAuth: true,\n allowedRoles: [],\n roleCheckMode: 'any'\n };\n\n /**\n * @zh 认证钩子\n * @en Auth hook\n */\n onAuth?(player: AuthPlayer<TUser>): boolean | Promise<boolean>;\n\n getAuthPlayer(id: string): AuthPlayer<TUser> | undefined {\n return undefined;\n }\n\n getAuthPlayers(): AuthPlayer<TUser>[] {\n return [];\n }\n\n getPlayersByRole(role: string): AuthPlayer<TUser>[] {\n return [];\n }\n\n getPlayerByUserId(userId: string): AuthPlayer<TUser> | undefined {\n return undefined;\n }\n}\n","/**\n * @zh requireAuth 装饰器\n * @en requireAuth decorator\n */\n\nimport type { RequireAuthOptions } from '../types.js';\n\n/**\n * @zh 认证元数据键\n * @en Auth metadata key\n */\nexport const AUTH_METADATA_KEY = Symbol('authMetadata');\n\n/**\n * @zh 认证元数据\n * @en Auth metadata\n */\nexport interface AuthMetadata {\n requireAuth: boolean;\n options?: RequireAuthOptions;\n roles?: string[];\n roleMode?: 'any' | 'all';\n}\n\n/**\n * @zh 获取方法的认证元数据\n * @en Get auth metadata for method\n */\nexport function getAuthMetadata(target: any, propertyKey: string): AuthMetadata | undefined {\n const metadata = target[AUTH_METADATA_KEY] as Map<string, AuthMetadata> | undefined;\n return metadata?.get(propertyKey);\n}\n\n/**\n * @zh 设置方法的认证元数据\n * @en Set auth metadata for method\n */\nfunction setAuthMetadata(target: any, propertyKey: string, metadata: AuthMetadata): void {\n if (!target[AUTH_METADATA_KEY]) {\n target[AUTH_METADATA_KEY] = new Map<string, AuthMetadata>();\n }\n (target[AUTH_METADATA_KEY] as Map<string, AuthMetadata>).set(propertyKey, metadata);\n}\n\n/**\n * @zh 要求认证装饰器\n * @en Require authentication decorator\n *\n * @zh 标记方法需要认证才能访问,用于消息处理器\n * @en Marks method as requiring authentication, used for message handlers\n *\n * @example\n * ```typescript\n * class GameRoom extends withRoomAuth(Room) {\n * @requireAuth()\n * @onMessage('Trade')\n * handleTrade(data: TradeData, player: AuthPlayer) {\n * // Only authenticated players can trade\n * }\n *\n * @requireAuth({ allowGuest: true })\n * @onMessage('Chat')\n * handleChat(data: ChatData, player: AuthPlayer) {\n * // Guests can also chat\n * }\n * }\n * ```\n */\nexport function requireAuth(options?: RequireAuthOptions): MethodDecorator {\n return function (\n target: any,\n propertyKey: string | symbol,\n descriptor: PropertyDescriptor\n ) {\n const key = String(propertyKey);\n const existing = getAuthMetadata(target, key);\n\n setAuthMetadata(target, key, {\n ...existing,\n requireAuth: true,\n options\n });\n\n return descriptor;\n };\n}\n","/**\n * @zh requireRole 装饰器\n * @en requireRole decorator\n */\n\nimport type { RequireRoleOptions } from '../types.js';\nimport { AUTH_METADATA_KEY, getAuthMetadata, type AuthMetadata } from './requireAuth.js';\n\n/**\n * @zh 设置方法的认证元数据\n * @en Set auth metadata for method\n */\nfunction setAuthMetadata(target: any, propertyKey: string, metadata: AuthMetadata): void {\n if (!target[AUTH_METADATA_KEY]) {\n target[AUTH_METADATA_KEY] = new Map<string, AuthMetadata>();\n }\n (target[AUTH_METADATA_KEY] as Map<string, AuthMetadata>).set(propertyKey, metadata);\n}\n\n/**\n * @zh 要求角色装饰器\n * @en Require role decorator\n *\n * @zh 标记方法需要特定角色才能访问\n * @en Marks method as requiring specific role(s)\n *\n * @example\n * ```typescript\n * class AdminRoom extends withRoomAuth(Room) {\n * @requireRole('admin')\n * @onMessage('Ban')\n * handleBan(data: BanData, player: AuthPlayer) {\n * // Only admins can ban\n * }\n *\n * @requireRole(['moderator', 'admin'])\n * @onMessage('Mute')\n * handleMute(data: MuteData, player: AuthPlayer) {\n * // Moderators or admins can mute\n * }\n *\n * @requireRole(['verified', 'premium'], { mode: 'all' })\n * @onMessage('SpecialFeature')\n * handleSpecial(data: any, player: AuthPlayer) {\n * // Requires both verified AND premium roles\n * }\n * }\n * ```\n */\nexport function requireRole(\n roles: string | string[],\n options?: RequireRoleOptions\n): MethodDecorator {\n return function (\n target: any,\n propertyKey: string | symbol,\n descriptor: PropertyDescriptor\n ) {\n const key = String(propertyKey);\n const existing = getAuthMetadata(target, key);\n const roleArray = Array.isArray(roles) ? roles : [roles];\n\n setAuthMetadata(target, key, {\n ...existing,\n requireAuth: true,\n roles: roleArray,\n roleMode: options?.mode ?? 'any',\n options\n });\n\n return descriptor;\n };\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as IAuthProvider, A as AuthResult } from '../../types-
|
|
2
|
-
import '../../index-
|
|
1
|
+
import { a as IAuthProvider, A as AuthResult } from '../../types-C7sS8Sfi.js';
|
|
2
|
+
import '../../index-lcuKuQsL.js';
|
|
3
3
|
import '@esengine/rpc';
|
|
4
4
|
import 'node:http';
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/auth/testing/MockAuthProvider.ts"],"names":["MockAuthProvider","config","name","_users","_config","_revokedTokens","Set","Map","users","user","set","id","_delay","delay","Promise","resolve","setTimeout","verify","token","defaultUser","success","error","errorCode","has","validateToken","get","expiresAt","Date","now","autoCreate","newUser","roles","refresh","revoke","add","addUser","removeUser","delete","getUser","getUsers","Array","from","values","clear","generateToken","userId","createMockAuthProvider"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @zh 模拟认证提供者\n * @en Mock authentication provider\n */\n\nimport type { IAuthProvider, AuthResult, AuthErrorCode } from '../types.js';\n\n/**\n * @zh 模拟用户\n * @en Mock user\n */\nexport interface MockUser {\n id: string;\n name?: string;\n roles?: string[];\n [key: string]: unknown;\n}\n\n/**\n * @zh 模拟认证配置\n * @en Mock authentication configuration\n */\nexport interface MockAuthConfig {\n /**\n * @zh 预设用户列表\n * @en Preset user list\n */\n users?: MockUser[];\n\n /**\n * @zh 默认用户(无 token 时返回)\n * @en Default user (returned when no token)\n */\n defaultUser?: MockUser;\n\n /**\n * @zh 模拟延迟(毫秒)\n * @en Simulated delay (ms)\n */\n delay?: number;\n\n /**\n * @zh 是否自动创建用户\n * @en Auto create users\n */\n autoCreate?: boolean;\n\n /**\n * @zh 验证令牌格式\n * @en Token format validator\n */\n validateToken?: (token: string) => boolean;\n}\n\n/**\n * @zh 模拟认证提供者\n * @en Mock authentication provider\n *\n * @zh 用于测试的认证提供者,不需要真实的 JWT 或数据库\n * @en Authentication provider for testing, no real JWT or database required\n *\n * @example\n * ```typescript\n * import { createMockAuthProvider } from '@esengine/server/auth/testing';\n *\n * const mockProvider = createMockAuthProvider({\n * users: [\n * { id: '1', name: 'Alice', roles: ['player'] },\n * { id: '2', name: 'Bob', roles: ['admin'] },\n * ],\n * autoCreate: true, // Unknown tokens create guest users\n * });\n *\n * // Verify with user ID as token\n * const result = await mockProvider.verify('1');\n * // result.user = { id: '1', name: 'Alice', roles: ['player'] }\n * ```\n */\nexport class MockAuthProvider<TUser extends MockUser = MockUser>\n implements IAuthProvider<TUser, string> {\n\n readonly name = 'mock';\n\n private _users: Map<string, TUser>;\n private _config: MockAuthConfig;\n private _revokedTokens: Set<string> = new Set();\n\n constructor(config: MockAuthConfig = {}) {\n this._config = config;\n this._users = new Map();\n\n if (config.users) {\n for (const user of config.users) {\n this._users.set(user.id, user as TUser);\n }\n }\n }\n\n /**\n * @zh 模拟延迟\n * @en Simulate delay\n */\n private async _delay(): Promise<void> {\n if (this._config.delay && this._config.delay > 0) {\n await new Promise(resolve => setTimeout(resolve, this._config.delay));\n }\n }\n\n /**\n * @zh 验证令牌\n * @en Verify token\n */\n async verify(token: string): Promise<AuthResult<TUser>> {\n await this._delay();\n\n if (!token) {\n if (this._config.defaultUser) {\n return {\n success: true,\n user: this._config.defaultUser as TUser,\n token: 'default'\n };\n }\n return {\n success: false,\n error: 'Token is required',\n errorCode: 'INVALID_TOKEN'\n };\n }\n\n if (this._revokedTokens.has(token)) {\n return {\n success: false,\n error: 'Token has been revoked',\n errorCode: 'INVALID_TOKEN'\n };\n }\n\n if (this._config.validateToken && !this._config.validateToken(token)) {\n return {\n success: false,\n error: 'Invalid token format',\n errorCode: 'INVALID_TOKEN'\n };\n }\n\n const user = this._users.get(token);\n\n if (user) {\n return {\n success: true,\n user,\n token,\n expiresAt: Date.now() + 3600000\n };\n }\n\n if (this._config.autoCreate) {\n const newUser = {\n id: token,\n name: `User_${token}`,\n roles: ['guest']\n } as TUser;\n\n this._users.set(token, newUser);\n\n return {\n success: true,\n user: newUser,\n token,\n expiresAt: Date.now() + 3600000\n };\n }\n\n return {\n success: false,\n error: 'User not found',\n errorCode: 'USER_NOT_FOUND'\n };\n }\n\n /**\n * @zh 刷新令牌\n * @en Refresh token\n */\n async refresh(token: string): Promise<AuthResult<TUser>> {\n return this.verify(token);\n }\n\n /**\n * @zh 撤销令牌\n * @en Revoke token\n */\n async revoke(token: string): Promise<boolean> {\n this._revokedTokens.add(token);\n return true;\n }\n\n /**\n * @zh 添加用户\n * @en Add user\n */\n addUser(user: TUser): void {\n this._users.set(user.id, user);\n }\n\n /**\n * @zh 移除用户\n * @en Remove user\n */\n removeUser(id: string): boolean {\n return this._users.delete(id);\n }\n\n /**\n * @zh 获取用户\n * @en Get user\n */\n getUser(id: string): TUser | undefined {\n return this._users.get(id);\n }\n\n /**\n * @zh 获取所有用户\n * @en Get all users\n */\n getUsers(): TUser[] {\n return Array.from(this._users.values());\n }\n\n /**\n * @zh 清空所有状态\n * @en Clear all state\n */\n clear(): void {\n this._users.clear();\n this._revokedTokens.clear();\n\n if (this._config.users) {\n for (const user of this._config.users) {\n this._users.set(user.id, user as TUser);\n }\n }\n }\n\n /**\n * @zh 生成测试令牌\n * @en Generate test token\n */\n generateToken(userId: string): string {\n return userId;\n }\n}\n\n/**\n * @zh 创建模拟认证提供者\n * @en Create mock authentication provider\n *\n * @example\n * ```typescript\n * const provider = createMockAuthProvider({\n * users: [\n * { id: 'admin', name: 'Admin', roles: ['admin'] }\n * ]\n * });\n *\n * // Use in tests\n * const server = withAuth(await createServer({ port: 0 }), {\n * provider,\n * extractCredentials: (req) => req.headers['x-token']\n * });\n * ```\n */\nexport function createMockAuthProvider<TUser extends MockUser = MockUser>(\n config?: MockAuthConfig\n): MockAuthProvider<TUser> {\n return new MockAuthProvider<TUser>(config);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/auth/testing/MockAuthProvider.ts"],"names":["MockAuthProvider","config","name","_users","_config","_revokedTokens","Set","Map","users","user","set","id","_delay","delay","Promise","resolve","setTimeout","verify","token","defaultUser","success","error","errorCode","has","validateToken","get","expiresAt","Date","now","autoCreate","newUser","roles","refresh","revoke","add","addUser","removeUser","delete","getUser","getUsers","Array","from","values","clear","generateToken","userId","createMockAuthProvider"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @zh 模拟认证提供者\n * @en Mock authentication provider\n */\n\nimport type { IAuthProvider, AuthResult, AuthErrorCode } from '../types.js';\n\n/**\n * @zh 模拟用户\n * @en Mock user\n */\nexport interface MockUser {\n id: string;\n name?: string;\n roles?: string[];\n [key: string]: unknown;\n}\n\n/**\n * @zh 模拟认证配置\n * @en Mock authentication configuration\n */\nexport interface MockAuthConfig {\n /**\n * @zh 预设用户列表\n * @en Preset user list\n */\n users?: MockUser[];\n\n /**\n * @zh 默认用户(无 token 时返回)\n * @en Default user (returned when no token)\n */\n defaultUser?: MockUser;\n\n /**\n * @zh 模拟延迟(毫秒)\n * @en Simulated delay (ms)\n */\n delay?: number;\n\n /**\n * @zh 是否自动创建用户\n * @en Auto create users\n */\n autoCreate?: boolean;\n\n /**\n * @zh 验证令牌格式\n * @en Token format validator\n */\n validateToken?: (token: string) => boolean;\n}\n\n/**\n * @zh 模拟认证提供者\n * @en Mock authentication provider\n *\n * @zh 用于测试的认证提供者,不需要真实的 JWT 或数据库\n * @en Authentication provider for testing, no real JWT or database required\n *\n * @example\n * ```typescript\n * import { createMockAuthProvider } from '@esengine/server/auth/testing';\n *\n * const mockProvider = createMockAuthProvider({\n * users: [\n * { id: '1', name: 'Alice', roles: ['player'] },\n * { id: '2', name: 'Bob', roles: ['admin'] },\n * ],\n * autoCreate: true, // Unknown tokens create guest users\n * });\n *\n * // Verify with user ID as token\n * const result = await mockProvider.verify('1');\n * // result.user = { id: '1', name: 'Alice', roles: ['player'] }\n * ```\n */\nexport class MockAuthProvider<TUser extends MockUser = MockUser>\nimplements IAuthProvider<TUser, string> {\n\n readonly name = 'mock';\n\n private _users: Map<string, TUser>;\n private _config: MockAuthConfig;\n private _revokedTokens: Set<string> = new Set();\n\n constructor(config: MockAuthConfig = {}) {\n this._config = config;\n this._users = new Map();\n\n if (config.users) {\n for (const user of config.users) {\n this._users.set(user.id, user as TUser);\n }\n }\n }\n\n /**\n * @zh 模拟延迟\n * @en Simulate delay\n */\n private async _delay(): Promise<void> {\n if (this._config.delay && this._config.delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, this._config.delay));\n }\n }\n\n /**\n * @zh 验证令牌\n * @en Verify token\n */\n async verify(token: string): Promise<AuthResult<TUser>> {\n await this._delay();\n\n if (!token) {\n if (this._config.defaultUser) {\n return {\n success: true,\n user: this._config.defaultUser as TUser,\n token: 'default'\n };\n }\n return {\n success: false,\n error: 'Token is required',\n errorCode: 'INVALID_TOKEN'\n };\n }\n\n if (this._revokedTokens.has(token)) {\n return {\n success: false,\n error: 'Token has been revoked',\n errorCode: 'INVALID_TOKEN'\n };\n }\n\n if (this._config.validateToken && !this._config.validateToken(token)) {\n return {\n success: false,\n error: 'Invalid token format',\n errorCode: 'INVALID_TOKEN'\n };\n }\n\n const user = this._users.get(token);\n\n if (user) {\n return {\n success: true,\n user,\n token,\n expiresAt: Date.now() + 3600000\n };\n }\n\n if (this._config.autoCreate) {\n const newUser = {\n id: token,\n name: `User_${token}`,\n roles: ['guest']\n } as TUser;\n\n this._users.set(token, newUser);\n\n return {\n success: true,\n user: newUser,\n token,\n expiresAt: Date.now() + 3600000\n };\n }\n\n return {\n success: false,\n error: 'User not found',\n errorCode: 'USER_NOT_FOUND'\n };\n }\n\n /**\n * @zh 刷新令牌\n * @en Refresh token\n */\n async refresh(token: string): Promise<AuthResult<TUser>> {\n return this.verify(token);\n }\n\n /**\n * @zh 撤销令牌\n * @en Revoke token\n */\n async revoke(token: string): Promise<boolean> {\n this._revokedTokens.add(token);\n return true;\n }\n\n /**\n * @zh 添加用户\n * @en Add user\n */\n addUser(user: TUser): void {\n this._users.set(user.id, user);\n }\n\n /**\n * @zh 移除用户\n * @en Remove user\n */\n removeUser(id: string): boolean {\n return this._users.delete(id);\n }\n\n /**\n * @zh 获取用户\n * @en Get user\n */\n getUser(id: string): TUser | undefined {\n return this._users.get(id);\n }\n\n /**\n * @zh 获取所有用户\n * @en Get all users\n */\n getUsers(): TUser[] {\n return Array.from(this._users.values());\n }\n\n /**\n * @zh 清空所有状态\n * @en Clear all state\n */\n clear(): void {\n this._users.clear();\n this._revokedTokens.clear();\n\n if (this._config.users) {\n for (const user of this._config.users) {\n this._users.set(user.id, user as TUser);\n }\n }\n }\n\n /**\n * @zh 生成测试令牌\n * @en Generate test token\n */\n generateToken(userId: string): string {\n return userId;\n }\n}\n\n/**\n * @zh 创建模拟认证提供者\n * @en Create mock authentication provider\n *\n * @example\n * ```typescript\n * const provider = createMockAuthProvider({\n * users: [\n * { id: 'admin', name: 'Admin', roles: ['admin'] }\n * ]\n * });\n *\n * // Use in tests\n * const server = withAuth(await createServer({ port: 0 }), {\n * provider,\n * extractCredentials: (req) => req.headers['x-token']\n * });\n * ```\n */\nexport function createMockAuthProvider<TUser extends MockUser = MockUser>(\n config?: MockAuthConfig\n): MockAuthProvider<TUser> {\n return new MockAuthProvider<TUser>(config);\n}\n"]}
|
|
@@ -334,5 +334,5 @@ function onMessage(type) {
|
|
|
334
334
|
__name(onMessage, "onMessage");
|
|
335
335
|
|
|
336
336
|
export { Player, Room, onMessage };
|
|
337
|
-
//# sourceMappingURL=chunk-
|
|
338
|
-
//# sourceMappingURL=chunk-
|
|
337
|
+
//# sourceMappingURL=chunk-FACTBKJ3.js.map
|
|
338
|
+
//# sourceMappingURL=chunk-FACTBKJ3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/room/Player.ts","../src/room/Room.ts","../src/room/decorators.ts"],"names":["Player","options","id","roomId","data","_conn","_sendFn","_leaveFn","conn","sendFn","leaveFn","initialData","connection","send","type","leave","reason","MESSAGE_HANDLERS","Room","maxPlayers","tickRate","autoDispose","state","_id","_players","Map","_locked","_disposed","_tickInterval","_lastTickTime","_broadcastFn","_disposeFn","players","Array","from","values","playerCount","size","isFull","isLocked","isDisposed","onCreate","onJoin","player","onLeave","onTick","dt","onDispose","broadcast","broadcastExcept","except","getPlayer","get","kick","lock","unlock","dispose","_stopTick","clear","_init","broadcastFn","disposeFn","_create","_startTick","_addPlayer","p","_removePlayer","set","delete","_handleMessage","playerId","handlers","handler","method","call","performance","now","setInterval","clearInterval","registerMessageHandler","target","push","onMessage","propertyKey","_descriptor"],"mappings":"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","file":"chunk-FACTBKJ3.js","sourcesContent":["/**\n * @zh 玩家类\n * @en Player class\n */\n\nimport type { Connection } from '@esengine/rpc';\n\n/**\n * @zh 玩家接口\n * @en Player interface\n */\nexport interface IPlayer<TData = Record<string, unknown>> {\n readonly id: string\n readonly roomId: string\n data: TData\n send<T>(type: string, data: T): void\n leave(reason?: string): void\n}\n\n/**\n * @zh 玩家实现\n * @en Player implementation\n */\nexport class Player<TData = Record<string, unknown>> implements IPlayer<TData> {\n readonly id: string;\n readonly roomId: string;\n data: TData;\n\n private _conn: Connection<any>;\n private _sendFn: (conn: Connection<any>, type: string, data: unknown) => void;\n private _leaveFn: (player: Player<TData>, reason?: string) => void;\n\n constructor(options: {\n id: string\n roomId: string\n conn: Connection<any>\n sendFn: (conn: Connection<any>, type: string, data: unknown) => void\n leaveFn: (player: Player<TData>, reason?: string) => void\n initialData?: TData\n }) {\n this.id = options.id;\n this.roomId = options.roomId;\n this._conn = options.conn;\n this._sendFn = options.sendFn;\n this._leaveFn = options.leaveFn;\n this.data = options.initialData ?? ({} as TData);\n }\n\n /**\n * @zh 获取底层连接\n * @en Get underlying connection\n */\n get connection(): Connection<any> {\n return this._conn;\n }\n\n /**\n * @zh 发送消息给玩家\n * @en Send message to player\n */\n send<T>(type: string, data: T): void {\n this._sendFn(this._conn, type, data);\n }\n\n /**\n * @zh 让玩家离开房间\n * @en Make player leave the room\n */\n leave(reason?: string): void {\n this._leaveFn(this, reason);\n }\n}\n","/**\n * @zh 房间基类\n * @en Room base class\n */\n\nimport { Player } from './Player.js';\n\n/**\n * @zh 房间配置\n * @en Room options\n */\nexport interface RoomOptions {\n [key: string]: unknown\n}\n\n/**\n * @zh 消息处理器元数据\n * @en Message handler metadata\n */\ninterface MessageHandlerMeta {\n type: string\n method: string\n}\n\n/**\n * @zh 消息处理器存储 key\n * @en Message handler storage key\n */\nconst MESSAGE_HANDLERS = Symbol('messageHandlers');\n\n/**\n * @zh 房间基类\n * @en Room base class\n *\n * @example\n * ```typescript\n * class GameRoom extends Room {\n * maxPlayers = 4\n * tickRate = 20\n *\n * onJoin(player: Player) {\n * this.broadcast('Joined', { id: player.id })\n * }\n *\n * @onMessage('Move')\n * handleMove(data: { x: number, y: number }, player: Player) {\n * // handle move\n * }\n * }\n * ```\n */\nexport abstract class Room<TState = any, TPlayerData = Record<string, unknown>> {\n // ========================================================================\n // 配置 | Configuration\n // ========================================================================\n\n /**\n * @zh 最大玩家数\n * @en Maximum players\n */\n maxPlayers = 16;\n\n /**\n * @zh Tick 速率(每秒),0 = 不自动 tick\n * @en Tick rate (per second), 0 = no auto tick\n */\n tickRate = 0;\n\n /**\n * @zh 空房间自动销毁\n * @en Auto dispose when empty\n */\n autoDispose = true;\n\n // ========================================================================\n // 状态 | State\n // ========================================================================\n\n /**\n * @zh 房间状态\n * @en Room state\n */\n state: TState = {} as TState;\n\n // ========================================================================\n // 内部属性 | Internal properties\n // ========================================================================\n\n private _id: string = '';\n private _players: Map<string, Player<TPlayerData>> = new Map();\n private _locked = false;\n private _disposed = false;\n private _tickInterval: ReturnType<typeof setInterval> | null = null;\n private _lastTickTime = 0;\n private _broadcastFn: ((type: string, data: unknown) => void) | null = null;\n private _sendFn: ((conn: any, type: string, data: unknown) => void) | null = null;\n private _disposeFn: (() => void) | null = null;\n\n // ========================================================================\n // 只读属性 | Readonly properties\n // ========================================================================\n\n /**\n * @zh 房间 ID\n * @en Room ID\n */\n get id(): string {\n return this._id;\n }\n\n /**\n * @zh 所有玩家\n * @en All players\n */\n get players(): ReadonlyArray<Player<TPlayerData>> {\n return Array.from(this._players.values());\n }\n\n /**\n * @zh 玩家数量\n * @en Player count\n */\n get playerCount(): number {\n return this._players.size;\n }\n\n /**\n * @zh 是否已满\n * @en Is full\n */\n get isFull(): boolean {\n return this._players.size >= this.maxPlayers;\n }\n\n /**\n * @zh 是否已锁定\n * @en Is locked\n */\n get isLocked(): boolean {\n return this._locked;\n }\n\n /**\n * @zh 是否已销毁\n * @en Is disposed\n */\n get isDisposed(): boolean {\n return this._disposed;\n }\n\n // ========================================================================\n // 生命周期 | Lifecycle\n // ========================================================================\n\n /**\n * @zh 房间创建时调用\n * @en Called when room is created\n */\n onCreate(options?: RoomOptions): void | Promise<void> {}\n\n /**\n * @zh 玩家加入时调用\n * @en Called when player joins\n */\n onJoin(player: Player<TPlayerData>): void | Promise<void> {}\n\n /**\n * @zh 玩家离开时调用\n * @en Called when player leaves\n */\n onLeave(player: Player<TPlayerData>, reason?: string): void | Promise<void> {}\n\n /**\n * @zh 游戏循环\n * @en Game tick\n */\n onTick(dt: number): void {}\n\n /**\n * @zh 房间销毁时调用\n * @en Called when room is disposed\n */\n onDispose(): void | Promise<void> {}\n\n // ========================================================================\n // 公共方法 | Public methods\n // ========================================================================\n\n /**\n * @zh 广播消息给所有玩家\n * @en Broadcast message to all players\n */\n broadcast<T>(type: string, data: T): void {\n for (const player of this._players.values()) {\n player.send(type, data);\n }\n }\n\n /**\n * @zh 广播消息给除指定玩家外的所有玩家\n * @en Broadcast message to all players except one\n */\n broadcastExcept<T>(except: Player<TPlayerData>, type: string, data: T): void {\n for (const player of this._players.values()) {\n if (player.id !== except.id) {\n player.send(type, data);\n }\n }\n }\n\n /**\n * @zh 获取玩家\n * @en Get player by id\n */\n getPlayer(id: string): Player<TPlayerData> | undefined {\n return this._players.get(id);\n }\n\n /**\n * @zh 踢出玩家\n * @en Kick player\n */\n kick(player: Player<TPlayerData>, reason?: string): void {\n player.leave(reason ?? 'kicked');\n }\n\n /**\n * @zh 锁定房间\n * @en Lock room\n */\n lock(): void {\n this._locked = true;\n }\n\n /**\n * @zh 解锁房间\n * @en Unlock room\n */\n unlock(): void {\n this._locked = false;\n }\n\n /**\n * @zh 手动销毁房间\n * @en Manually dispose room\n */\n dispose(): void {\n if (this._disposed) return;\n this._disposed = true;\n\n this._stopTick();\n\n for (const player of this._players.values()) {\n player.leave('room_disposed');\n }\n this._players.clear();\n\n this.onDispose();\n this._disposeFn?.();\n }\n\n // ========================================================================\n // 内部方法 | Internal methods\n // ========================================================================\n\n /**\n * @internal\n */\n _init(options: {\n id: string\n sendFn: (conn: any, type: string, data: unknown) => void\n broadcastFn: (type: string, data: unknown) => void\n disposeFn: () => void\n }): void {\n this._id = options.id;\n this._sendFn = options.sendFn;\n this._broadcastFn = options.broadcastFn;\n this._disposeFn = options.disposeFn;\n }\n\n /**\n * @internal\n */\n async _create(options?: RoomOptions): Promise<void> {\n await this.onCreate(options);\n this._startTick();\n }\n\n /**\n * @internal\n */\n async _addPlayer(id: string, conn: any): Promise<Player<TPlayerData> | null> {\n if (this._locked || this.isFull || this._disposed) {\n return null;\n }\n\n const player = new Player<TPlayerData>({\n id,\n roomId: this._id,\n conn,\n sendFn: this._sendFn!,\n leaveFn: (p, reason) => this._removePlayer(p.id, reason)\n });\n\n this._players.set(id, player);\n await this.onJoin(player);\n\n return player;\n }\n\n /**\n * @internal\n */\n async _removePlayer(id: string, reason?: string): Promise<void> {\n const player = this._players.get(id);\n if (!player) return;\n\n this._players.delete(id);\n await this.onLeave(player, reason);\n\n if (this.autoDispose && this._players.size === 0) {\n this.dispose();\n }\n }\n\n /**\n * @internal\n */\n _handleMessage(type: string, data: unknown, playerId: string): void {\n const player = this._players.get(playerId);\n if (!player) return;\n\n const handlers = (this.constructor as any)[MESSAGE_HANDLERS] as MessageHandlerMeta[] | undefined;\n if (handlers) {\n for (const handler of handlers) {\n if (handler.type === type) {\n const method = (this as any)[handler.method];\n if (typeof method === 'function') {\n method.call(this, data, player);\n }\n }\n }\n }\n }\n\n private _startTick(): void {\n if (this.tickRate <= 0) return;\n\n this._lastTickTime = performance.now();\n this._tickInterval = setInterval(() => {\n const now = performance.now();\n const dt = (now - this._lastTickTime) / 1000;\n this._lastTickTime = now;\n this.onTick(dt);\n }, 1000 / this.tickRate);\n }\n\n private _stopTick(): void {\n if (this._tickInterval) {\n clearInterval(this._tickInterval);\n this._tickInterval = null;\n }\n }\n}\n\n/**\n * @zh 获取消息处理器元数据\n * @en Get message handler metadata\n */\nexport function getMessageHandlers(target: any): MessageHandlerMeta[] {\n return target[MESSAGE_HANDLERS] || [];\n}\n\n/**\n * @zh 注册消息处理器元数据\n * @en Register message handler metadata\n */\nexport function registerMessageHandler(target: any, type: string, method: string): void {\n if (!target[MESSAGE_HANDLERS]) {\n target[MESSAGE_HANDLERS] = [];\n }\n target[MESSAGE_HANDLERS].push({ type, method });\n}\n","/**\n * @zh 房间装饰器\n * @en Room decorators\n */\n\nimport { registerMessageHandler } from './Room.js';\n\n/**\n * @zh 消息处理器装饰器\n * @en Message handler decorator\n *\n * @example\n * ```typescript\n * class GameRoom extends Room {\n * @onMessage('Move')\n * handleMove(data: { x: number, y: number }, player: Player) {\n * // handle move\n * }\n *\n * @onMessage('Chat')\n * handleChat(data: { text: string }, player: Player) {\n * this.broadcast('Chat', { from: player.id, text: data.text })\n * }\n * }\n * ```\n */\nexport function onMessage(type: string): MethodDecorator {\n return function (\n target: any,\n propertyKey: string | symbol,\n _descriptor: PropertyDescriptor\n ) {\n registerMessageHandler(target.constructor, type, propertyKey as string);\n };\n}\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { __name } from './chunk-T626JPC7.js';
|
|
2
|
+
import { createLogger as createLogger$1 } from '@esengine/ecs-framework';
|
|
3
|
+
|
|
4
|
+
function createLogger(name) {
|
|
5
|
+
return createLogger$1(name);
|
|
6
|
+
}
|
|
7
|
+
__name(createLogger, "createLogger");
|
|
8
|
+
createLogger("Server");
|
|
9
|
+
|
|
10
|
+
export { createLogger };
|
|
11
|
+
//# sourceMappingURL=chunk-I4QQSQ72.js.map
|
|
12
|
+
//# sourceMappingURL=chunk-I4QQSQ72.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/logger.ts"],"names":["createLogger","name","ecsCreateLogger"],"mappings":";;;AAyBO,SAASA,aAAaC,IAAAA,EAAY;AACrC,EAAA,OAAOC,eAAgBD,IAAAA,CAAAA;AAC3B;AAFgBD,MAAAA,CAAAA,YAAAA,EAAAA,cAAAA,CAAAA;AAQYA,aAAa,QAAA","file":"chunk-I4QQSQ72.js","sourcesContent":["/**\n * @zh 日志模块 - 直接使用 @esengine/ecs-framework 的 Logger\n * @en Logger module - Uses @esengine/ecs-framework Logger directly\n */\n\nimport { createLogger as ecsCreateLogger, type ILogger } from '@esengine/ecs-framework';\n\nexport type { ILogger };\n\n/**\n * @zh 创建命名日志器\n * @en Create a named logger\n *\n * @param name - @zh 日志器名称 @en Logger name\n * @returns @zh 日志器实例 @en Logger instance\n *\n * @example\n * ```typescript\n * import { createLogger } from './logger.js'\n *\n * const logger = createLogger('Server')\n * logger.info('Started on port 3000')\n * logger.error('Connection failed:', error)\n * ```\n */\nexport function createLogger(name: string): ILogger {\n return ecsCreateLogger(name);\n}\n\n/**\n * @zh 默认服务器日志器\n * @en Default server logger\n */\nexport const serverLogger = createLogger('Server');\n"]}
|