@moxon/api 6.0.0-pre → 6.2.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/README.md +44 -19
- package/dist/app.js +9 -4
- package/dist/app.js.map +1 -1
- package/dist/constants.d.ts +22 -0
- package/dist/constants.js +22 -0
- package/dist/constants.js.map +1 -1
- package/dist/endpoints/define.d.ts +30 -0
- package/dist/endpoints/define.js +14 -0
- package/dist/endpoints/define.js.map +1 -0
- package/dist/endpoints/hash.d.ts +2 -0
- package/dist/endpoints/hash.js +16 -0
- package/dist/endpoints/hash.js.map +1 -0
- package/dist/endpoints/index.d.ts +2 -0
- package/dist/endpoints/index.js +4 -0
- package/dist/endpoints/index.js.map +1 -0
- package/dist/endpoints/router.d.ts +10 -0
- package/dist/endpoints/router.js +50 -0
- package/dist/endpoints/router.js.map +1 -0
- package/dist/manifest.d.ts +11 -0
- package/dist/manifest.js +12 -0
- package/dist/manifest.js.map +1 -0
- package/dist/middleware/cors.d.ts +15 -0
- package/dist/middleware/cors.js +25 -7
- package/dist/middleware/cors.js.map +1 -1
- package/dist/middleware/ratelimit.d.ts +53 -1
- package/dist/middleware/ratelimit.js +180 -71
- package/dist/middleware/ratelimit.js.map +1 -1
- package/dist/modules/v4/barcode.d.ts +1 -1
- package/dist/modules/v4/barcode.js +9 -2
- package/dist/modules/v4/barcode.js.map +1 -1
- package/dist/modules/v4/captcha.d.ts +1 -1
- package/dist/modules/v4/captcha.js +5 -1
- package/dist/modules/v4/captcha.js.map +1 -1
- package/dist/modules/v4/chat.js +61 -12
- package/dist/modules/v4/chat.js.map +1 -1
- package/dist/modules/v4/cron.js +20 -2
- package/dist/modules/v4/cron.js.map +1 -1
- package/dist/modules/v4/hyperplanning.d.ts +11 -0
- package/dist/modules/v4/hyperplanning.js +30 -29
- package/dist/modules/v4/hyperplanning.js.map +1 -1
- package/dist/modules/v4/qrcode.d.ts +10 -0
- package/dist/modules/v4/qrcode.js +138 -14
- package/dist/modules/v4/qrcode.js.map +1 -1
- package/dist/modules/v4/regex.d.ts +1 -1
- package/dist/modules/v4/regex.js +67 -22
- package/dist/modules/v4/regex.js.map +1 -1
- package/dist/modules/v4/tic_tac_toe.js +56 -15
- package/dist/modules/v4/tic_tac_toe.js.map +1 -1
- package/dist/modules/v5/asymmetric.d.ts +15 -0
- package/dist/modules/v5/asymmetric.js +67 -5
- package/dist/modules/v5/asymmetric.js.map +1 -1
- package/dist/modules/v5/barcode.d.ts +1 -1
- package/dist/modules/v5/barcode.js +9 -2
- package/dist/modules/v5/barcode.js.map +1 -1
- package/dist/modules/v5/captcha.d.ts +12 -4
- package/dist/modules/v5/captcha.js +25 -8
- package/dist/modules/v5/captcha.js.map +1 -1
- package/dist/modules/v5/chat.js +66 -17
- package/dist/modules/v5/chat.js.map +1 -1
- package/dist/modules/v5/cron.d.ts +26 -0
- package/dist/modules/v5/cron.js +356 -0
- package/dist/modules/v5/cron.js.map +1 -0
- package/dist/modules/v5/pow.js +1 -1
- package/dist/modules/v5/pow.js.map +1 -1
- package/dist/modules/v5/tic_tac_toe.js +61 -20
- package/dist/modules/v5/tic_tac_toe.js.map +1 -1
- package/dist/modules/v5.d.ts +3 -2
- package/dist/modules/v5.js +3 -2
- package/dist/modules/v5.js.map +1 -1
- package/dist/routes/delete.js +0 -8
- package/dist/routes/delete.js.map +1 -1
- package/dist/routes/get.js +0 -2
- package/dist/routes/get.js.map +1 -1
- package/dist/routes/patch.js +0 -4
- package/dist/routes/patch.js.map +1 -1
- package/dist/routes/post.js +12 -25
- package/dist/routes/post.js.map +1 -1
- package/dist/storage/index.js +9 -8
- package/dist/storage/index.js.map +1 -1
- package/dist/types/storage.d.ts +4 -0
- package/dist/utils/challenge.d.ts +5 -3
- package/dist/utils/challenge.js +52 -6
- package/dist/utils/challenge.js.map +1 -1
- package/dist/utils/helpers.d.ts +18 -0
- package/dist/utils/helpers.js +35 -1
- package/dist/utils/helpers.js.map +1 -1
- package/dist/utils/remote.d.ts +42 -0
- package/dist/utils/remote.js +313 -0
- package/dist/utils/remote.js.map +1 -0
- package/package.json +28 -8
- package/src/favicon.ico +0 -0
|
@@ -6,22 +6,30 @@ export interface CaptchaChallenge {
|
|
|
6
6
|
body: Buffer;
|
|
7
7
|
token: string;
|
|
8
8
|
}
|
|
9
|
+
export interface CaptchaVerification {
|
|
10
|
+
valid: boolean;
|
|
11
|
+
reason?: ChallengeVerification['reason'] | 'weak';
|
|
12
|
+
}
|
|
9
13
|
/**
|
|
10
14
|
* Generates a hardened captcha whose answer is bound to a signed token instead
|
|
11
15
|
* of being returned in clear. The answer lives only inside the HMAC, so the
|
|
12
|
-
* caller holds a token it cannot read the solution from.
|
|
16
|
+
* caller holds a token it cannot read the solution from. The token also
|
|
17
|
+
* carries the answer length in clear, signed along with the answer, so the
|
|
18
|
+
* verifying side can refuse a captcha generated too short to resist guessing.
|
|
13
19
|
*
|
|
14
20
|
* @param options - Captcha configuration options
|
|
15
21
|
* @returns PNG buffer, content type, and the token to verify the answer against
|
|
16
|
-
* @throws Error if any option is out of the accepted range
|
|
22
|
+
* @throws Error if the text is too long or any option is out of the accepted range
|
|
17
23
|
*/
|
|
18
24
|
export default function captchaChallenge(options: CaptchaOptions): CaptchaChallenge;
|
|
19
25
|
/**
|
|
20
|
-
* Verifies a captcha answer against its token, then consumes the token.
|
|
26
|
+
* Verifies a captcha answer against its token, then consumes the token. Only a
|
|
27
|
+
* captcha token is accepted, and it is burnt after too many wrong answers.
|
|
21
28
|
*
|
|
22
29
|
* @param token - Token issued alongside the challenge image
|
|
23
30
|
* @param answer - Answer read by the user, compared case-insensitively
|
|
24
31
|
* @param storage - Store of already consumed nonces
|
|
32
|
+
* @param minLength - Shortest answer accepted; a correct answer to a shorter captcha is refused as weak
|
|
25
33
|
* @returns Verification result, with a reason when it fails
|
|
26
34
|
*/
|
|
27
|
-
export declare function verifyCaptcha(token: string, answer: string, storage: ChallengeStorage):
|
|
35
|
+
export declare function verifyCaptcha(token: string, answer: string, storage: ChallengeStorage, minLength?: number): CaptchaVerification;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createCanvas } from 'canvas';
|
|
2
|
-
import {
|
|
2
|
+
import { MAX_CAPTCHA_TEXT_LENGTH } from '../../constants.js';
|
|
3
|
+
import { readToken, signToken, verifyToken } from '../../utils/challenge.js';
|
|
3
4
|
import { normalizeColor } from '../../utils/colors.js';
|
|
4
5
|
const NOISE_LEVELS = new Set(['low', 'medium', 'high']);
|
|
5
6
|
const NOISE_CONFIG = { low: { lines: 8, dots: 80 }, medium: { lines: 25, dots: 300 }, high: { lines: 50, dots: 600 } };
|
|
@@ -32,9 +33,12 @@ const muted = () => `rgb(${Math.floor(Math.random() * 180)}, ${Math.floor(Math.r
|
|
|
32
33
|
*
|
|
33
34
|
* @param options - Captcha configuration options
|
|
34
35
|
* @returns Object containing the PNG buffer, content type, and the challenge text
|
|
35
|
-
* @throws Error if any option is out of the accepted range
|
|
36
|
+
* @throws Error if the text is too long or any option is out of the accepted range
|
|
36
37
|
*/
|
|
37
38
|
function hardened(options) {
|
|
39
|
+
if (options.text && options.text.length > MAX_CAPTCHA_TEXT_LENGTH) {
|
|
40
|
+
throw new Error(`Text cannot exceed ${MAX_CAPTCHA_TEXT_LENGTH} characters`);
|
|
41
|
+
}
|
|
38
42
|
const text = options.text || generateText(clamp(options.length, 'length', 6, 1, 20));
|
|
39
43
|
const height = clamp(options.height, 'height', 120, 50, 400);
|
|
40
44
|
const width = clamp(options.width, 'width', text.length * 60, 100, 800);
|
|
@@ -112,25 +116,38 @@ function hardened(options) {
|
|
|
112
116
|
/**
|
|
113
117
|
* Generates a hardened captcha whose answer is bound to a signed token instead
|
|
114
118
|
* of being returned in clear. The answer lives only inside the HMAC, so the
|
|
115
|
-
* caller holds a token it cannot read the solution from.
|
|
119
|
+
* caller holds a token it cannot read the solution from. The token also
|
|
120
|
+
* carries the answer length in clear, signed along with the answer, so the
|
|
121
|
+
* verifying side can refuse a captcha generated too short to resist guessing.
|
|
116
122
|
*
|
|
117
123
|
* @param options - Captcha configuration options
|
|
118
124
|
* @returns PNG buffer, content type, and the token to verify the answer against
|
|
119
|
-
* @throws Error if any option is out of the accepted range
|
|
125
|
+
* @throws Error if the text is too long or any option is out of the accepted range
|
|
120
126
|
*/
|
|
121
127
|
export default function captchaChallenge(options) {
|
|
122
128
|
const { contentType, body, text } = hardened(options);
|
|
123
|
-
|
|
129
|
+
const { length } = text;
|
|
130
|
+
return { contentType, body, token: signToken('img', `${length}.${text.toLowerCase()}`, { length }) };
|
|
124
131
|
}
|
|
125
132
|
/**
|
|
126
|
-
* Verifies a captcha answer against its token, then consumes the token.
|
|
133
|
+
* Verifies a captcha answer against its token, then consumes the token. Only a
|
|
134
|
+
* captcha token is accepted, and it is burnt after too many wrong answers.
|
|
127
135
|
*
|
|
128
136
|
* @param token - Token issued alongside the challenge image
|
|
129
137
|
* @param answer - Answer read by the user, compared case-insensitively
|
|
130
138
|
* @param storage - Store of already consumed nonces
|
|
139
|
+
* @param minLength - Shortest answer accepted; a correct answer to a shorter captcha is refused as weak
|
|
131
140
|
* @returns Verification result, with a reason when it fails
|
|
132
141
|
*/
|
|
133
|
-
export function verifyCaptcha(token, answer, storage) {
|
|
134
|
-
|
|
142
|
+
export function verifyCaptcha(token, answer, storage, minLength) {
|
|
143
|
+
const normalized = answer.trim().toLowerCase();
|
|
144
|
+
const length = readToken(token)?.length;
|
|
145
|
+
const signed = typeof length === 'number';
|
|
146
|
+
// Tokens issued before the length was signed carry the bare answer
|
|
147
|
+
const result = verifyToken(token, signed ? `${length}.${normalized}` : normalized, storage, 'img');
|
|
148
|
+
if (result.valid && minLength !== undefined && !(signed && length >= minLength)) {
|
|
149
|
+
return { valid: false, reason: 'weak' };
|
|
150
|
+
}
|
|
151
|
+
return result;
|
|
135
152
|
}
|
|
136
153
|
//# sourceMappingURL=captcha.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"captcha.js","sourceRoot":"","sources":["../../../src/modules/v5/captcha.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"captcha.js","sourceRoot":"","sources":["../../../src/modules/v5/captcha.ts"],"names":[],"mappings":"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"}
|
package/dist/modules/v5/chat.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { SESSION_TTL } from '../../constants.js';
|
|
2
|
-
import { checkRateLimit } from '../../utils/helpers.js';
|
|
1
|
+
import { MAX_CHAT_MESSAGES, MAX_ID_LENGTH, MAX_PRIVATE_CHATS, MAX_STRING_LENGTH, MAX_USERNAME_LENGTH, SESSION_TTL, } from '../../constants.js';
|
|
2
|
+
import { checkRateLimit, checkString, isTimestamp } from '../../utils/helpers.js';
|
|
3
3
|
/**
|
|
4
4
|
* Handles real-time chat actions including sending, fetching, and clearing messages.
|
|
5
5
|
*
|
|
@@ -11,12 +11,17 @@ import { checkRateLimit } from '../../utils/helpers.js';
|
|
|
11
11
|
export default function chat(action, params) {
|
|
12
12
|
const storage = params.storage;
|
|
13
13
|
storage.messages ??= [];
|
|
14
|
-
storage.privateChats ??=
|
|
15
|
-
storage.sessions ??=
|
|
16
|
-
storage.rateLimits ??=
|
|
14
|
+
storage.privateChats ??= Object.create(null);
|
|
15
|
+
storage.sessions ??= Object.create(null);
|
|
16
|
+
storage.rateLimits ??= Object.create(null);
|
|
17
17
|
const { messages, privateChats, sessions, rateLimits } = storage;
|
|
18
18
|
if (!params.username)
|
|
19
19
|
throw new Error('Please provide a username');
|
|
20
|
+
// Readers are keyed by their IP, which can be longer than a chat username
|
|
21
|
+
checkString(params.username, 'username', action === 'fetch' ? MAX_STRING_LENGTH : MAX_USERNAME_LENGTH);
|
|
22
|
+
checkString(params.message, 'message', MAX_STRING_LENGTH);
|
|
23
|
+
checkString(params.session, 'session ID', MAX_ID_LENGTH);
|
|
24
|
+
checkString(params.token, 'token', MAX_ID_LENGTH);
|
|
20
25
|
const u = params.username.toLowerCase();
|
|
21
26
|
const now = Date.now();
|
|
22
27
|
checkRateLimit(rateLimits, u, now);
|
|
@@ -36,27 +41,46 @@ export default function chat(action, params) {
|
|
|
36
41
|
throw new Error('Invalid action. Use "message", "private", "fetch", or "clear"');
|
|
37
42
|
}
|
|
38
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Stores a message in the public room or in the private thread of its token.
|
|
46
|
+
*
|
|
47
|
+
* @param params - Chat parameters holding the message, session and optional private token
|
|
48
|
+
* @param messages - Public room, trimmed to its newest MAX_CHAT_MESSAGES entries
|
|
49
|
+
* @param privateChats - Private threads keyed by token, each trimmed the same way
|
|
50
|
+
* @param sessions - Session bound to each lowercased username
|
|
51
|
+
* @param u - Lowercased username
|
|
52
|
+
* @param now - Current timestamp in milliseconds
|
|
53
|
+
* @returns Confirmation message
|
|
54
|
+
* @throws Error if the message or session is missing, the session does not match, or too many private chats exist
|
|
55
|
+
*/
|
|
39
56
|
function sendMessage(params, messages, privateChats, sessions, u, now) {
|
|
40
57
|
const { message, session, token } = params;
|
|
41
58
|
if (!message)
|
|
42
59
|
throw new Error('Please provide a message');
|
|
43
60
|
if (!session)
|
|
44
61
|
throw new Error('Please provide a valid session ID');
|
|
45
|
-
if (sessions
|
|
62
|
+
if (Object.hasOwn(sessions, u) && sessions[u].user !== session) {
|
|
46
63
|
throw new Error('Session ID mismatch');
|
|
47
64
|
}
|
|
48
65
|
const msg = {
|
|
49
66
|
username: params.username,
|
|
50
67
|
message,
|
|
51
|
-
timestamp: params.timestamp
|
|
68
|
+
timestamp: params.timestamp && isTimestamp(params.timestamp) ? params.timestamp : new Date().toISOString(),
|
|
52
69
|
};
|
|
53
70
|
if (token) {
|
|
54
|
-
privateChats
|
|
55
|
-
|
|
71
|
+
if (!Object.hasOwn(privateChats, token)) {
|
|
72
|
+
if (Object.keys(privateChats).length >= MAX_PRIVATE_CHATS)
|
|
73
|
+
throw new Error('Too many active private chats');
|
|
74
|
+
privateChats[token] = [];
|
|
75
|
+
}
|
|
76
|
+
const thread = privateChats[token];
|
|
77
|
+
thread.push(msg);
|
|
78
|
+
if (thread.length > MAX_CHAT_MESSAGES)
|
|
79
|
+
thread.splice(0, thread.length - MAX_CHAT_MESSAGES);
|
|
56
80
|
setTimeout(() => {
|
|
57
|
-
|
|
58
|
-
if (!thread)
|
|
81
|
+
if (!Object.hasOwn(privateChats, token))
|
|
59
82
|
return;
|
|
83
|
+
const thread = privateChats[token];
|
|
60
84
|
const idx = thread.indexOf(msg);
|
|
61
85
|
if (idx !== -1)
|
|
62
86
|
thread.splice(idx, 1);
|
|
@@ -66,21 +90,36 @@ function sendMessage(params, messages, privateChats, sessions, u, now) {
|
|
|
66
90
|
}
|
|
67
91
|
else {
|
|
68
92
|
messages.push(msg);
|
|
69
|
-
|
|
93
|
+
if (messages.length > MAX_CHAT_MESSAGES)
|
|
94
|
+
messages.splice(0, messages.length - MAX_CHAT_MESSAGES);
|
|
95
|
+
setTimeout(() => {
|
|
96
|
+
const idx = messages.indexOf(msg);
|
|
97
|
+
if (idx !== -1)
|
|
98
|
+
messages.splice(idx, 1);
|
|
99
|
+
}, SESSION_TTL).unref();
|
|
70
100
|
}
|
|
71
|
-
|
|
101
|
+
if (!Object.hasOwn(sessions, u))
|
|
102
|
+
sessions[u] = { user: session, last: now };
|
|
72
103
|
sessions[u].last = now;
|
|
73
104
|
setTimeout(() => {
|
|
74
|
-
if (sessions
|
|
105
|
+
if (Object.hasOwn(sessions, u) && Date.now() - sessions[u].last >= SESSION_TTL)
|
|
75
106
|
delete sessions[u];
|
|
76
107
|
}, SESSION_TTL).unref();
|
|
77
108
|
return { message: 'Message sent successfully' };
|
|
78
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* Returns the messages of a private thread.
|
|
112
|
+
*
|
|
113
|
+
* @param params - Chat parameters holding the private token
|
|
114
|
+
* @param privateChats - Private threads keyed by token
|
|
115
|
+
* @returns Messages of the thread, oldest first
|
|
116
|
+
* @throws Error if the token is missing or no thread exists for it
|
|
117
|
+
*/
|
|
79
118
|
function getPrivateChat(params, privateChats) {
|
|
80
119
|
const { token } = params;
|
|
81
120
|
if (!token)
|
|
82
121
|
throw new Error('Please provide a valid token');
|
|
83
|
-
if (privateChats
|
|
122
|
+
if (Object.hasOwn(privateChats, token))
|
|
84
123
|
return privateChats[token];
|
|
85
124
|
throw new Error('Invalid or expired token.');
|
|
86
125
|
}
|
|
@@ -89,16 +128,26 @@ function fetchMessages(messages) {
|
|
|
89
128
|
return messages;
|
|
90
129
|
throw new Error('No messages stored.');
|
|
91
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Deletes a private thread and the session of the user clearing it.
|
|
133
|
+
*
|
|
134
|
+
* @param params - Chat parameters holding the private token and session
|
|
135
|
+
* @param privateChats - Private threads keyed by token
|
|
136
|
+
* @param sessions - Session bound to each lowercased username
|
|
137
|
+
* @param u - Lowercased username
|
|
138
|
+
* @returns Confirmation message
|
|
139
|
+
* @throws Error if the token or session is missing, the session does not match, or no thread exists for the token
|
|
140
|
+
*/
|
|
92
141
|
function clearPrivateChat(params, privateChats, sessions, u) {
|
|
93
142
|
const { token, session } = params;
|
|
94
143
|
if (!token)
|
|
95
144
|
throw new Error('Please provide a valid token');
|
|
96
145
|
if (!session)
|
|
97
146
|
throw new Error('Please provide a valid session ID');
|
|
98
|
-
if (sessions
|
|
147
|
+
if (Object.hasOwn(sessions, u) && sessions[u].user !== session) {
|
|
99
148
|
throw new Error('Session ID mismatch');
|
|
100
149
|
}
|
|
101
|
-
if (!privateChats
|
|
150
|
+
if (!Object.hasOwn(privateChats, token))
|
|
102
151
|
throw new Error('Invalid or expired token.');
|
|
103
152
|
delete privateChats[token];
|
|
104
153
|
delete sessions[u];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.js","sourceRoot":"","sources":["../../../src/modules/v5/chat.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"chat.js","sourceRoot":"","sources":["../../../src/modules/v5/chat.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CronResult } from '../v4/cron.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parses a cron expression and returns the next scheduled execution dates.
|
|
4
|
+
*
|
|
5
|
+
* @param expr - Cron expression with 5 space-separated fields (minute hour dom month dow)
|
|
6
|
+
* @param count - Number of next executions to return (1-20, default 5)
|
|
7
|
+
* @param from - Starting date in ISO 8601 format (defaults to now)
|
|
8
|
+
* @param timezone - Timezone to evaluate the expression in (default "UTC")
|
|
9
|
+
* @returns Parsed expression with description and list of next execution timestamps
|
|
10
|
+
* @throws Error if the expression is invalid, count is out of range, or timezone is unsupported
|
|
11
|
+
*/
|
|
12
|
+
export default function cron(expr: string, count?: number, from?: string, timezone?: string): CronResult;
|
|
13
|
+
/**
|
|
14
|
+
* Runs the cron search and also tells whether it listed every date the schedule will ever have.
|
|
15
|
+
*
|
|
16
|
+
* @param expr - Cron expression with 5 space-separated fields (minute hour dom month dow)
|
|
17
|
+
* @param count - Number of next executions to look for (1-20)
|
|
18
|
+
* @param from - Starting date in ISO 8601 format (defaults to now)
|
|
19
|
+
* @param timezone - Timezone to evaluate the expression in
|
|
20
|
+
* @returns The cron result, and complete set when fewer than count dates exist after from
|
|
21
|
+
* @throws Error if the expression is invalid, count is out of range, or timezone is unsupported
|
|
22
|
+
*/
|
|
23
|
+
export declare function cronSearch(expr: string, count: number, from: string | undefined, timezone: string): {
|
|
24
|
+
result: CronResult;
|
|
25
|
+
complete: boolean;
|
|
26
|
+
};
|