feat: add redemption code system (#1133)

feat: add redemption code support
This commit is contained in:
Dream Hunter
2026-09-05 22:19:17 +08:00
committed by GitHub
parent 8e1bfb8af2
commit 66ab5a05df
53 changed files with 4718 additions and 309 deletions
+16 -8
View File
@@ -7,7 +7,9 @@ export const WORKER_URL_SUBDOMAIN = process.env.WORKER_URL_SUBDOMAIN || '';
export const WORKER_URL_ENV_OFF = process.env.WORKER_URL_ENV_OFF || '';
export const WORKER_GZIP_URL = process.env.WORKER_GZIP_URL || '';
export const WORKER_URL_SEND_MAIL_DOMAIN = process.env.WORKER_URL_SEND_MAIL_DOMAIN || '';
export const WORKER_URL_SITE_PASSWORD = process.env.WORKER_URL_SITE_PASSWORD || '';
export const FRONTEND_URL = process.env.FRONTEND_URL!;
export const FRONTEND_URL_ENV_OFF = process.env.FRONTEND_URL_ENV_OFF || '';
export const MAILPIT_API = process.env.MAILPIT_API!;
export const TEST_DOMAIN = 'test.example.com';
@@ -165,14 +167,20 @@ export function onMailpitMessage(
ws.on('open', () => readyResolve());
ws.on('message', (data: WebSocket.Data) => {
try {
const event = JSON.parse(data.toString());
if (event.Type === 'new' && predicate(event.Data)) {
clearTimeout(timer);
ws.close();
if (!settled) { settled = true; resolve(event.Data); }
}
} catch { /* ignore parse errors */ }
// Mailpit may batch multiple newline-separated events in one message.
for (const line of data.toString().split('\n')) {
if (settled) return;
try {
const event = JSON.parse(line);
if (event.Type === 'new' && predicate(event.Data)) {
clearTimeout(timer);
settled = true;
ws.close();
resolve(event.Data);
return;
}
} catch { /* ignore malformed events without dropping the remaining ones */ }
}
});
ws.on('close', () => {
+3
View File
@@ -19,11 +19,14 @@ BLACK_LIST = ""
ENABLE_USER_CREATE_EMAIL = true
ENABLE_USER_DELETE_EMAIL = true
ENABLE_MAIL_READ_STATUS = true
ENABLE_REDEEM_CODE = true
REDEEM_CODE_URL = "https://example.com/redeem-codes"
ENABLE_AUTO_REPLY = true
DEFAULT_SEND_BALANCE = 10
NO_LIMIT_SEND_ROLE = "case-role"
ENABLE_ADDRESS_PASSWORD = true
DISABLE_ADMIN_PASSWORD_CHECK = true
ADMIN_USER_ROLE = "admin"
ADMIN_PASSWORDS = '["e2e-admin-pass"]'
ENABLE_WEBHOOK = true
E2E_TEST_MODE = true
+1
View File
@@ -13,6 +13,7 @@ JWT_SECRET = "e2e-test-secret-key-env-off"
BLACK_LIST = ""
ENABLE_USER_CREATE_EMAIL = true
ENABLE_USER_DELETE_EMAIL = false
ENABLE_REDEEM_CODE = false
ENABLE_AUTO_REPLY = true
DEFAULT_SEND_BALANCE = 10
ENABLE_ADDRESS_PASSWORD = true
@@ -0,0 +1,32 @@
name = "cloudflare_temp_email_site_password"
main = "src/worker.ts"
compatibility_date = "2025-04-01"
compatibility_flags = [ "nodejs_compat" ]
keep_vars = true
[vars]
PREFIX = "tmp"
DEFAULT_DOMAINS = ["test.example.com"]
DOMAINS = ["test.example.com"]
USER_ROLES = [
{ domains = ["test.example.com"], role = "case-role", prefix = "" },
]
ADMIN_USER_ROLE = "admin"
JWT_SECRET = "e2e-site-password-secret"
PASSWORDS = '["e2e-site-pass"]'
BLACK_LIST = ""
ENABLE_REDEEM_CODE = true
ENABLE_ADDRESS_PASSWORD = true
ADDRESS_CHECK_REGEX = "^(?!.*blocked).*$"
DISABLE_ADMIN_PASSWORD_CHECK = false
ADMIN_PASSWORDS = '["e2e-admin-pass"]'
E2E_TEST_MODE = true
[[kv_namespaces]]
binding = "KV"
id = "e2e-test-kv-site-password-00000000-0000-0000-0000-000000000000"
[[d1_databases]]
binding = "DB"
database_name = "e2e-temp-email-site-password"
database_id = "e2e-test-db-site-password-00000000-0000-0000-0000-000000000000"