@syncar/server 1.0.0-alpha.2 → 1.0.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +111 -148
- package/dist/index.d.ts +329 -2519
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/middleware/index.d.ts +160 -0
- package/dist/middleware/index.js +2 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/types-DeE5vqYX.d.ts +630 -0
- package/package.json +5 -1
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { d as IContext, e as IMiddlewareAction, b as IMiddleware, C as ChannelName, I as IClientConnection } from '../types-DeE5vqYX.js';
|
|
2
|
+
import 'ws';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Auth middleware options
|
|
6
|
+
*/
|
|
7
|
+
interface AuthOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Verify and decode a token
|
|
10
|
+
* Returns the user data to attach to the client
|
|
11
|
+
*/
|
|
12
|
+
verifyToken: (token: string) => Promise<unknown> | unknown;
|
|
13
|
+
/**
|
|
14
|
+
* Extract token from the middleware context
|
|
15
|
+
*/
|
|
16
|
+
getToken?: (c: IContext) => string | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Property name to attach verified user data
|
|
19
|
+
* @default 'user'
|
|
20
|
+
*/
|
|
21
|
+
attachProperty?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Actions to require authentication
|
|
24
|
+
* @default All actions require auth
|
|
25
|
+
*/
|
|
26
|
+
actions?: IMiddlewareAction[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Create an authentication middleware
|
|
30
|
+
*
|
|
31
|
+
* This middleware verifies tokens and attaches user data to clients.
|
|
32
|
+
* Rejects connections that fail authentication.
|
|
33
|
+
*/
|
|
34
|
+
declare function authenticate(options: AuthOptions): IMiddleware;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Logging middleware options
|
|
38
|
+
*/
|
|
39
|
+
interface LoggingOptions {
|
|
40
|
+
/**
|
|
41
|
+
* Logger instance to use
|
|
42
|
+
* @default console
|
|
43
|
+
*/
|
|
44
|
+
logger?: Pick<Console, 'log' | 'info' | 'warn' | 'error'>;
|
|
45
|
+
/**
|
|
46
|
+
* Log level
|
|
47
|
+
* @default 'info'
|
|
48
|
+
*/
|
|
49
|
+
logLevel?: 'log' | 'info' | 'warn' | 'error';
|
|
50
|
+
/**
|
|
51
|
+
* Whether to include message data in logs
|
|
52
|
+
* @default false
|
|
53
|
+
*/
|
|
54
|
+
includeMessageData?: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Custom format function for log output
|
|
57
|
+
*/
|
|
58
|
+
format?: (context: {
|
|
59
|
+
action: string;
|
|
60
|
+
clientId?: string;
|
|
61
|
+
channel?: string;
|
|
62
|
+
message?: unknown;
|
|
63
|
+
duration?: number;
|
|
64
|
+
}) => string;
|
|
65
|
+
/**
|
|
66
|
+
* Actions to log
|
|
67
|
+
* @default All actions are logged
|
|
68
|
+
*/
|
|
69
|
+
actions?: IMiddlewareAction[];
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Create a logging middleware
|
|
73
|
+
*
|
|
74
|
+
* Logs all middleware actions with client and action information.
|
|
75
|
+
*/
|
|
76
|
+
declare function logger(options?: LoggingOptions): IMiddleware;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Rate limit middleware options
|
|
80
|
+
*/
|
|
81
|
+
interface RateLimitOptions {
|
|
82
|
+
/**
|
|
83
|
+
* Maximum number of requests allowed per window
|
|
84
|
+
* @default 100
|
|
85
|
+
*/
|
|
86
|
+
maxRequests?: number;
|
|
87
|
+
/**
|
|
88
|
+
* Time window in milliseconds
|
|
89
|
+
* @default 60000 (1 minute)
|
|
90
|
+
*/
|
|
91
|
+
windowMs?: number;
|
|
92
|
+
/**
|
|
93
|
+
* Extract a unique identifier for rate limiting
|
|
94
|
+
* Defaults to client ID
|
|
95
|
+
*/
|
|
96
|
+
getMessageId?: (c: IContext) => string;
|
|
97
|
+
/**
|
|
98
|
+
* Actions to rate limit
|
|
99
|
+
* @default 'message' only
|
|
100
|
+
*/
|
|
101
|
+
actions?: IMiddlewareAction[];
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Rate limit state for each client
|
|
105
|
+
*/
|
|
106
|
+
interface RateLimitState {
|
|
107
|
+
count: number;
|
|
108
|
+
resetTime: number;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Create a rate limiting middleware
|
|
112
|
+
*
|
|
113
|
+
* Limits the rate of requests per client within a time window.
|
|
114
|
+
*/
|
|
115
|
+
declare function rateLimit(options?: RateLimitOptions): IMiddleware;
|
|
116
|
+
/**
|
|
117
|
+
* Clear the rate limit store
|
|
118
|
+
* Useful for testing or manual reset
|
|
119
|
+
*/
|
|
120
|
+
declare function clearRateLimitStore(): void;
|
|
121
|
+
/**
|
|
122
|
+
* Get rate limit state for a specific client
|
|
123
|
+
*
|
|
124
|
+
* @param id - Client or message ID
|
|
125
|
+
* @returns Rate limit state or undefined
|
|
126
|
+
*/
|
|
127
|
+
declare function getRateLimitState(id: string): RateLimitState | undefined;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Channel whitelist middleware options
|
|
131
|
+
*/
|
|
132
|
+
interface ChannelWhitelistOptions {
|
|
133
|
+
/**
|
|
134
|
+
* List of allowed channels
|
|
135
|
+
* If isDynamic is true, this is used as a fallback
|
|
136
|
+
*/
|
|
137
|
+
allowedChannels?: ChannelName[];
|
|
138
|
+
/**
|
|
139
|
+
* Dynamic check function for channel access
|
|
140
|
+
* If provided, this takes precedence over allowedChannels
|
|
141
|
+
*
|
|
142
|
+
* @param channel - The channel name to check
|
|
143
|
+
* @param client - The client attempting to access the channel
|
|
144
|
+
* @returns true if channel is allowed
|
|
145
|
+
*/
|
|
146
|
+
isDynamic?: (channel: ChannelName, client?: IClientConnection) => boolean;
|
|
147
|
+
/**
|
|
148
|
+
* Whether to also check unsubscribe actions
|
|
149
|
+
* @default false (only restrict subscribe)
|
|
150
|
+
*/
|
|
151
|
+
restrictUnsubscribe?: boolean;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Create a channel whitelist middleware
|
|
155
|
+
*
|
|
156
|
+
* Restricts which channels clients can subscribe to.
|
|
157
|
+
*/
|
|
158
|
+
declare function channelWhitelist(options?: ChannelWhitelistOptions): IMiddleware;
|
|
159
|
+
|
|
160
|
+
export { type AuthOptions, type ChannelWhitelistOptions, type LoggingOptions, type RateLimitOptions, authenticate, channelWhitelist, clearRateLimitStore, getRateLimitState, logger, rateLimit };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function f(s){let{verifyToken:c,getToken:a=e=>e.req.message?.data?.token,attachProperty:d="user",actions:t}=s;return async(e,i)=>{if(t&&!t.includes(e.req.action))return i();let n=a(e);if(!n)return e.reject("Authentication token required");try{let r=await c(n);e.req.client&&(e.req.client[d]=r),e.set(d,r),await i()}catch{e.reject("Authentication failed: Invalid token")}}}function p(s={}){let{logger:c=console,logLevel:a="info",includeMessageData:d=!1,format:t,actions:e}=s;return async(i,n)=>{if(e&&!e.includes(i.req.action))return n();let r=Date.now();await n();let o=Date.now()-r,u={action:i.req.action,clientId:i.req.client?.id,channel:i.req.channel,message:d?i.req.message:void 0,duration:o},m=t?t(u):`[${u.action}] Client: ${u.clientId??"unknown"}${u.channel?` Channel: ${u.channel}`:""} (${o}ms)`;c[a](m)}}var l=new Map;function w(s={}){let{maxRequests:c=100,windowMs:a=6e4,getMessageId:d=n=>n.req.client?.id??"",actions:t=["message"]}=s,e=setInterval(()=>{let n=Date.now();for(let[r,o]of l)o.resetTime<n&&l.delete(r)},a*10),i=async(n,r)=>{if(!t.includes(n.req.action))return r();let o=d(n);if(!o)return r();let u=Date.now(),m=l.get(o);m&&m.resetTime<u&&l.delete(o);let g=l.get(o);if(g||(g={count:0,resetTime:u+a},l.set(o,g)),g.count>=c)return n.reject(`Rate limit exceeded. Max ${c} requests per ${a}ms`);g.count++,await r()};return i.cleanup=()=>{clearInterval(e),l.clear()},i}function h(){l.clear()}function I(s){return l.get(s)}function q(s={}){let{allowedChannels:c=[],isDynamic:a,restrictUnsubscribe:d=!1}=s;return async(t,e)=>{if(t.req.action!=="subscribe"&&t.req.action!=="unsubscribe"||t.req.action==="unsubscribe"&&!d||!t.req.channel)return e();if(a)return a(t.req.channel,t.req.client)?e():t.reject(`Channel '${t.req.channel}' is not allowed`);if(!c.includes(t.req.channel))return t.reject(`Channel '${t.req.channel}' is not allowed`);await e()}}export{f as authenticate,q as channelWhitelist,h as clearRateLimitStore,I as getRateLimitState,p as logger,w as rateLimit};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/middleware/authenticate.ts","../../src/middleware/logger.ts","../../src/middleware/rate-limit.ts","../../src/middleware/channel-whitelist.ts"],"sourcesContent":["import type { IMiddleware, IContext, IMiddlewareAction } from '../types'\n\n/**\n * Auth middleware options\n */\nexport interface AuthOptions {\n /**\n * Verify and decode a token\n * Returns the user data to attach to the client\n */\n verifyToken: (token: string) => Promise<unknown> | unknown\n\n /**\n * Extract token from the middleware context\n */\n getToken?: (c: IContext) => string | undefined\n\n /**\n * Property name to attach verified user data\n * @default 'user'\n */\n attachProperty?: string\n\n /**\n * Actions to require authentication\n * @default All actions require auth\n */\n actions?: IMiddlewareAction[]\n}\n\n/**\n * Create an authentication middleware\n *\n * This middleware verifies tokens and attaches user data to clients.\n * Rejects connections that fail authentication.\n */\nexport function authenticate(options: AuthOptions): IMiddleware {\n const {\n verifyToken,\n getToken = (c) => {\n // Default: extract token from message.data.token\n const msg = c.req.message as\n | { data?: { token?: string } }\n | undefined\n return msg?.data?.token\n },\n attachProperty = 'user',\n actions,\n } = options\n\n return async (c, next) => {\n // Check if this action requires auth\n if (actions && !actions.includes(c.req.action)) {\n return next()\n }\n\n // Extract token\n const token = getToken(c)\n if (!token) {\n return c.reject('Authentication token required')\n }\n\n // Verify token\n try {\n const userData = await verifyToken(token!)\n\n // Attach user data to client (LEGACY - for compatibility)\n if (c.req.client) {\n ;(c.req.client as unknown as Record<string, unknown>)[\n attachProperty\n ] = userData\n }\n\n // Attach to STATE (Hono-style)\n c.set(attachProperty, userData)\n\n // PASS TO NEXT LAYER\n await next()\n } catch (error) {\n c.reject('Authentication failed: Invalid token')\n }\n }\n}\n","import type { IMiddleware, IMiddlewareAction } from '../types'\n\n/**\n * Logging middleware options\n */\nexport interface LoggingOptions {\n /**\n * Logger instance to use\n * @default console\n */\n logger?: Pick<Console, 'log' | 'info' | 'warn' | 'error'>\n\n /**\n * Log level\n * @default 'info'\n */\n logLevel?: 'log' | 'info' | 'warn' | 'error'\n\n /**\n * Whether to include message data in logs\n * @default false\n */\n includeMessageData?: boolean\n\n /**\n * Custom format function for log output\n */\n format?: (context: {\n action: string\n clientId?: string\n channel?: string\n message?: unknown\n duration?: number\n }) => string\n\n /**\n * Actions to log\n * @default All actions are logged\n */\n actions?: IMiddlewareAction[]\n}\n\n/**\n * Create a logging middleware\n *\n * Logs all middleware actions with client and action information.\n */\nexport function logger(options: LoggingOptions = {}): IMiddleware {\n const {\n logger = console,\n logLevel = 'info',\n includeMessageData = false,\n format,\n actions,\n } = options\n\n return async (c, next) => {\n // Check if this action should be logged\n if (actions && !actions.includes(c.req.action)) {\n return next()\n }\n\n const start = Date.now()\n\n await next() // Wait for downstream layers\n\n const duration = Date.now() - start\n\n const logData = {\n action: c.req.action,\n clientId: c.req.client?.id,\n channel: c.req.channel,\n message: includeMessageData ? c.req.message : undefined,\n duration,\n }\n\n const logMessage = format\n ? format(logData)\n : `[${logData.action}] Client: ${logData.clientId ?? 'unknown'}${logData.channel ? ` Channel: ${logData.channel}` : ''} (${duration}ms)`\n\n logger[logLevel](logMessage)\n }\n}\n","import type { IMiddleware, IContext, IMiddlewareAction } from '../types'\n\n/**\n * Rate limit middleware options\n */\nexport interface RateLimitOptions {\n /**\n * Maximum number of requests allowed per window\n * @default 100\n */\n maxRequests?: number\n\n /**\n * Time window in milliseconds\n * @default 60000 (1 minute)\n */\n windowMs?: number\n\n /**\n * Extract a unique identifier for rate limiting\n * Defaults to client ID\n */\n getMessageId?: (c: IContext) => string\n\n /**\n * Actions to rate limit\n * @default 'message' only\n */\n actions?: IMiddlewareAction[]\n}\n\n/**\n * Rate limit state for each client\n */\nexport interface RateLimitState {\n count: number\n resetTime: number\n}\n\n/**\n * Rate limit storage\n * Maps client ID to rate limit state\n */\nconst rateLimitStore = new Map<string, RateLimitState>()\n\n/**\n * Create a rate limiting middleware\n *\n * Limits the rate of requests per client within a time window.\n */\nexport function rateLimit(options: RateLimitOptions = {}): IMiddleware {\n const {\n maxRequests = 100,\n windowMs = 60000,\n getMessageId = (c) => c.req.client?.id ?? '',\n actions = ['message'],\n } = options\n\n // Clean up expired entries periodically (every 10 windows)\n const cleanupInterval = setInterval(() => {\n const now = Date.now()\n for (const [id, state] of rateLimitStore) {\n if (state.resetTime < now) {\n rateLimitStore.delete(id)\n }\n }\n }, windowMs * 10)\n\n // Return middleware with cleanup\n const middleware: IMiddleware = async (c, next) => {\n // Check if this action should be rate limited\n if (!actions.includes(c.req.action)) {\n return next()\n }\n\n const id = getMessageId(c)\n if (!id) {\n return next() // No ID to rate limit\n }\n\n const now = Date.now()\n const state = rateLimitStore.get(id)\n\n // Check if window has expired\n if (state && state.resetTime < now) {\n rateLimitStore.delete(id)\n }\n\n // Get or create state\n let currentState = rateLimitStore.get(id)\n if (!currentState) {\n currentState = {\n count: 0,\n resetTime: now + windowMs,\n }\n rateLimitStore.set(id, currentState)\n }\n\n // Check limit\n if (currentState.count >= maxRequests) {\n return c.reject(\n `Rate limit exceeded. Max ${maxRequests} requests per ${windowMs}ms`,\n )\n }\n\n // Increment counter\n currentState.count++\n\n // CONTINUE\n await next()\n }\n\n // Attach cleanup method\n ;(middleware as { cleanup?: () => void }).cleanup = () => {\n clearInterval(cleanupInterval)\n rateLimitStore.clear()\n }\n\n return middleware\n}\n\n/**\n * Clear the rate limit store\n * Useful for testing or manual reset\n */\nexport function clearRateLimitStore(): void {\n rateLimitStore.clear()\n}\n\n/**\n * Get rate limit state for a specific client\n *\n * @param id - Client or message ID\n * @returns Rate limit state or undefined\n */\nexport function getRateLimitState(id: string): RateLimitState | undefined {\n return rateLimitStore.get(id)\n}\n","import type { IMiddleware, IClientConnection, ChannelName } from '../types'\n\n/**\n * Channel whitelist middleware options\n */\nexport interface ChannelWhitelistOptions {\n /**\n * List of allowed channels\n * If isDynamic is true, this is used as a fallback\n */\n allowedChannels?: ChannelName[]\n\n /**\n * Dynamic check function for channel access\n * If provided, this takes precedence over allowedChannels\n *\n * @param channel - The channel name to check\n * @param client - The client attempting to access the channel\n * @returns true if channel is allowed\n */\n isDynamic?: (channel: ChannelName, client?: IClientConnection) => boolean\n\n /**\n * Whether to also check unsubscribe actions\n * @default false (only restrict subscribe)\n */\n restrictUnsubscribe?: boolean\n}\n\n/**\n * Create a channel whitelist middleware\n *\n * Restricts which channels clients can subscribe to.\n */\nexport function channelWhitelist(\n options: ChannelWhitelistOptions = {},\n): IMiddleware {\n const {\n allowedChannels = [],\n isDynamic,\n restrictUnsubscribe = false,\n } = options\n\n return async (c, next) => {\n // Only check subscribe/unsubscribe actions\n if (c.req.action !== 'subscribe' && c.req.action !== 'unsubscribe') {\n return next()\n }\n\n // Skip unsubscribe if not restricted\n if (c.req.action === 'unsubscribe' && !restrictUnsubscribe) {\n return next()\n }\n\n if (!c.req.channel) {\n return next() // No channel to check\n }\n\n // Check dynamic function first\n if (isDynamic) {\n if (!isDynamic(c.req.channel, c.req.client)) {\n return c.reject(`Channel '${c.req.channel}' is not allowed`)\n }\n return next()\n }\n\n // Check static whitelist\n if (!allowedChannels.includes(c.req.channel)) {\n return c.reject(`Channel '${c.req.channel}' is not allowed`)\n }\n\n await next()\n }\n}\n"],"mappings":"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","names":["authenticate","options","verifyToken","getToken","c","attachProperty","actions","next","token","userData","logger","options","logLevel","includeMessageData","format","actions","c","next","start","duration","logData","logMessage","rateLimitStore","rateLimit","options","maxRequests","windowMs","getMessageId","c","actions","cleanupInterval","now","id","state","middleware","next","currentState","clearRateLimitStore","getRateLimitState","channelWhitelist","options","allowedChannels","isDynamic","restrictUnsubscribe","c","next"]}
|