notifkit 0.1.7 → 0.1.8
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/dashboard/README.md +29 -0
- package/dashboard/dist/assets/index-7mvXb4bS.js +310 -0
- package/dashboard/dist/assets/index-o7L-f3-c.css +1 -0
- package/dashboard/dist/favicon.svg +4 -0
- package/dashboard/dist/index.html +14 -0
- package/dist/index.d.mts +433 -8
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{main-D6SG3Isk.mjs → main-0FHNtN5g.mjs} +2 -2
- package/dist/{main-D6SG3Isk.mjs.map → main-0FHNtN5g.mjs.map} +1 -1
- package/dist/{main-pFAfCkVX.mjs → main-7KMlWnDx.mjs} +2 -2
- package/dist/{main-pFAfCkVX.mjs.map → main-7KMlWnDx.mjs.map} +1 -1
- package/dist/{main-Bgi2wWck.mjs → main-B0BcY_JJ.mjs} +2 -2
- package/dist/{main-Bgi2wWck.mjs.map → main-B0BcY_JJ.mjs.map} +1 -1
- package/dist/{main-CFSukWm8.mjs → main-BAO4kKce.mjs} +366 -26
- package/dist/main-BAO4kKce.mjs.map +1 -0
- package/dist/{main-CRPxM-O3.mjs → main-BjXgGJBd.mjs} +2 -2
- package/dist/{main-CRPxM-O3.mjs.map → main-BjXgGJBd.mjs.map} +1 -1
- package/dist/{main-CjbVdUqa.mjs → main-BtXITy0k.mjs} +2 -2
- package/dist/{main-CjbVdUqa.mjs.map → main-BtXITy0k.mjs.map} +1 -1
- package/dist/{main-Yorxzw0Z.mjs → main-BxqAXTr6.mjs} +2 -2
- package/dist/{main-Yorxzw0Z.mjs.map → main-BxqAXTr6.mjs.map} +1 -1
- package/dist/{main-DFMHcN_d.mjs → main-zCpvA9Rx.mjs} +2 -2
- package/dist/{main-DFMHcN_d.mjs.map → main-zCpvA9Rx.mjs.map} +1 -1
- package/dist/{src-CPMwsUCJ.mjs → src-DkvHYM3y.mjs} +76 -19
- package/dist/src-DkvHYM3y.mjs.map +1 -0
- package/drizzle/0005_admin_users.sql +11 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +8 -3
- package/scripts/create-admin.mjs +67 -0
- package/src/config/index.ts +3 -0
- package/src/db/schema.ts +13 -0
- package/src/repositories/index.ts +82 -1
- package/src/services/api/admin-static.ts +224 -0
- package/src/services/api/handlers.ts +129 -12
- package/src/services/api/main.ts +72 -19
- package/src/services/auth/index.ts +103 -0
- package/dist/main-CFSukWm8.mjs.map +0 -1
- package/dist/src-CPMwsUCJ.mjs.map +0 -1
|
@@ -7,7 +7,7 @@ import { createHmac, randomUUID, timingSafeEqual } from "node:crypto";
|
|
|
7
7
|
import postgres from "postgres";
|
|
8
8
|
import { drizzle } from "drizzle-orm/postgres-js";
|
|
9
9
|
import { boolean, check, index, integer, jsonb, pgEnum, pgTable, primaryKey, text, time, timestamp, unique, uuid, varchar } from "drizzle-orm/pg-core";
|
|
10
|
-
import { and, desc, eq, inArray, sql } from "drizzle-orm";
|
|
10
|
+
import { and, desc, eq, inArray, or, sql } from "drizzle-orm";
|
|
11
11
|
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
|
|
12
12
|
import { migrate } from "drizzle-orm/postgres-js/migrator";
|
|
13
13
|
import { fileURLToPath } from "url";
|
|
@@ -69,6 +69,9 @@ const baseConfigSchema = z.object({
|
|
|
69
69
|
REDIS_URL: z.string().url().default("redis://localhost:6379"),
|
|
70
70
|
DATABASE_URL: z.string().url().default("postgres://platform:platform@localhost:5432/notifkit"),
|
|
71
71
|
ADMIN_API_KEY: z.string().trim().optional(),
|
|
72
|
+
ADMIN_EMAIL: z.string().trim().email().optional(),
|
|
73
|
+
ADMIN_PASSWORD: z.string().trim().min(6).optional(),
|
|
74
|
+
ADMIN_USERNAME: z.string().trim().optional(),
|
|
72
75
|
WORKER_CONCURRENCY: z.coerce.number().int().min(1).default(10),
|
|
73
76
|
QUEUE_MAX_LEN: z.coerce.number().int().min(1).default(1e7),
|
|
74
77
|
DB_MAX_CONNECTIONS: z.coerce.number().int().min(1).default(2),
|
|
@@ -673,10 +676,12 @@ registry.define("notification.ai_pending", NotificationAiPendingPayloadSchema);
|
|
|
673
676
|
//#endregion
|
|
674
677
|
//#region src/db/schema.ts
|
|
675
678
|
var schema_exports = /* @__PURE__ */ __exportAll({
|
|
679
|
+
adminUsers: () => adminUsers,
|
|
676
680
|
apiKeyRoleEnum: () => apiKeyRoleEnum,
|
|
677
681
|
channelEnum: () => channelEnum,
|
|
678
682
|
contactTopicPreferences: () => contactTopicPreferences,
|
|
679
683
|
deliveryOutbox: () => deliveryOutbox,
|
|
684
|
+
insertAdminUserSchema: () => insertAdminUserSchema,
|
|
680
685
|
insertDeliveryOutboxSchema: () => insertDeliveryOutboxSchema,
|
|
681
686
|
insertMessageLogSchema: () => insertMessageLogSchema,
|
|
682
687
|
insertProjectApiKeySchema: () => insertProjectApiKeySchema,
|
|
@@ -696,6 +701,7 @@ var schema_exports = /* @__PURE__ */ __exportAll({
|
|
|
696
701
|
projects: () => projects,
|
|
697
702
|
quietHours: () => quietHours,
|
|
698
703
|
scheduledPayloads: () => scheduledPayloads,
|
|
704
|
+
selectAdminUserSchema: () => selectAdminUserSchema,
|
|
699
705
|
selectDeliveryOutboxSchema: () => selectDeliveryOutboxSchema,
|
|
700
706
|
selectMessageLogSchema: () => selectMessageLogSchema,
|
|
701
707
|
selectProjectApiKeySchema: () => selectProjectApiKeySchema,
|
|
@@ -941,6 +947,17 @@ const scheduledPayloads = pgTable("scheduled_payloads", {
|
|
|
941
947
|
payload: jsonb("payload").notNull(),
|
|
942
948
|
createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull()
|
|
943
949
|
});
|
|
950
|
+
const adminUsers = pgTable("admin_users", {
|
|
951
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
952
|
+
email: varchar("email").notNull().unique(),
|
|
953
|
+
username: varchar("username").unique(),
|
|
954
|
+
passwordHash: varchar("password_hash").notNull(),
|
|
955
|
+
role: varchar("role").notNull().default("admin"),
|
|
956
|
+
createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(),
|
|
957
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull()
|
|
958
|
+
});
|
|
959
|
+
const insertAdminUserSchema = createInsertSchema(adminUsers);
|
|
960
|
+
const selectAdminUserSchema = createSelectSchema(adminUsers);
|
|
944
961
|
const insertProjectSchema = createInsertSchema(projects);
|
|
945
962
|
const selectProjectSchema = createSelectSchema(projects);
|
|
946
963
|
const insertProjectApiKeySchema = createInsertSchema(projectApiKeys);
|
|
@@ -2567,6 +2584,46 @@ var SegmentRepository = class {
|
|
|
2567
2584
|
`)).map((r) => r.segment);
|
|
2568
2585
|
}
|
|
2569
2586
|
};
|
|
2587
|
+
var AdminUserRepository = class {
|
|
2588
|
+
db;
|
|
2589
|
+
constructor(db) {
|
|
2590
|
+
this.db = db;
|
|
2591
|
+
}
|
|
2592
|
+
async findByEmailOrUsername(identifier) {
|
|
2593
|
+
const normalized = identifier.trim().toLowerCase();
|
|
2594
|
+
return (await this.db.select().from(adminUsers).where(or(eq(adminUsers.email, normalized), eq(adminUsers.username, identifier.trim()))).limit(1))[0] ?? null;
|
|
2595
|
+
}
|
|
2596
|
+
async findById(id) {
|
|
2597
|
+
return (await this.db.select().from(adminUsers).where(eq(adminUsers.id, id)).limit(1))[0] ?? null;
|
|
2598
|
+
}
|
|
2599
|
+
async create(data) {
|
|
2600
|
+
return (await this.db.insert(adminUsers).values({
|
|
2601
|
+
email: data.email.trim().toLowerCase(),
|
|
2602
|
+
username: data.username ? data.username.trim() : null,
|
|
2603
|
+
passwordHash: data.passwordHash,
|
|
2604
|
+
role: data.role || "admin"
|
|
2605
|
+
}).returning())[0];
|
|
2606
|
+
}
|
|
2607
|
+
async updatePassword(id, passwordHash) {
|
|
2608
|
+
return (await this.db.update(adminUsers).set({
|
|
2609
|
+
passwordHash,
|
|
2610
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
2611
|
+
}).where(eq(adminUsers.id, id)).returning()).length > 0;
|
|
2612
|
+
}
|
|
2613
|
+
async list() {
|
|
2614
|
+
return await this.db.select({
|
|
2615
|
+
id: adminUsers.id,
|
|
2616
|
+
email: adminUsers.email,
|
|
2617
|
+
username: adminUsers.username,
|
|
2618
|
+
role: adminUsers.role,
|
|
2619
|
+
createdAt: adminUsers.createdAt,
|
|
2620
|
+
updatedAt: adminUsers.updatedAt
|
|
2621
|
+
}).from(adminUsers).orderBy(adminUsers.createdAt);
|
|
2622
|
+
}
|
|
2623
|
+
async count() {
|
|
2624
|
+
return (await this.db.select({ count: sql`count(*)::int` }).from(adminUsers))[0]?.count ?? 0;
|
|
2625
|
+
}
|
|
2626
|
+
};
|
|
2570
2627
|
//#endregion
|
|
2571
2628
|
//#region src/templates/render.ts
|
|
2572
2629
|
function escapeHtml(unsafe) {
|
|
@@ -3402,35 +3459,35 @@ var NotifkitServer = class extends EventEmitter {
|
|
|
3402
3459
|
}
|
|
3403
3460
|
const startupPromises = [];
|
|
3404
3461
|
if (services.includes("api")) {
|
|
3405
|
-
const { startApiServer } = await import("./main-
|
|
3462
|
+
const { startApiServer } = await import("./main-BAO4kKce.mjs");
|
|
3406
3463
|
startupPromises.push(startApiServer());
|
|
3407
3464
|
}
|
|
3408
3465
|
if (services.includes("delivery")) {
|
|
3409
|
-
const { startDeliveryWorker } = await import("./main-
|
|
3466
|
+
const { startDeliveryWorker } = await import("./main-7KMlWnDx.mjs");
|
|
3410
3467
|
startupPromises.push(startDeliveryWorker());
|
|
3411
3468
|
}
|
|
3412
3469
|
if (services.includes("engine")) {
|
|
3413
|
-
const { startEngineWorker } = await import("./main-
|
|
3470
|
+
const { startEngineWorker } = await import("./main-BxqAXTr6.mjs");
|
|
3414
3471
|
startupPromises.push(startEngineWorker());
|
|
3415
3472
|
}
|
|
3416
3473
|
if (services.includes("enricher")) {
|
|
3417
|
-
const { startEnricherWorker } = await import("./main-
|
|
3474
|
+
const { startEnricherWorker } = await import("./main-B0BcY_JJ.mjs");
|
|
3418
3475
|
startupPromises.push(startEnricherWorker());
|
|
3419
3476
|
}
|
|
3420
3477
|
if (services.includes("scheduler")) {
|
|
3421
|
-
const { startSchedulerWorker } = await import("./main-
|
|
3478
|
+
const { startSchedulerWorker } = await import("./main-zCpvA9Rx.mjs");
|
|
3422
3479
|
startupPromises.push(startSchedulerWorker());
|
|
3423
3480
|
}
|
|
3424
3481
|
if (services.includes("ai")) {
|
|
3425
|
-
const { startAiWorker } = await import("./main-
|
|
3482
|
+
const { startAiWorker } = await import("./main-0FHNtN5g.mjs");
|
|
3426
3483
|
startupPromises.push(startAiWorker());
|
|
3427
3484
|
}
|
|
3428
3485
|
if (services.includes("workflow")) {
|
|
3429
|
-
const { startWorkflowWorker } = await import("./main-
|
|
3486
|
+
const { startWorkflowWorker } = await import("./main-BtXITy0k.mjs");
|
|
3430
3487
|
startupPromises.push(startWorkflowWorker());
|
|
3431
3488
|
}
|
|
3432
3489
|
if (services.includes("events")) {
|
|
3433
|
-
const { startEventWorker } = await import("./main-
|
|
3490
|
+
const { startEventWorker } = await import("./main-BjXgGJBd.mjs");
|
|
3434
3491
|
startupPromises.push(startEventWorker());
|
|
3435
3492
|
}
|
|
3436
3493
|
const handleSignal = async (signal) => {
|
|
@@ -3470,35 +3527,35 @@ var NotifkitServer = class extends EventEmitter {
|
|
|
3470
3527
|
"events"
|
|
3471
3528
|
] : this.options.services;
|
|
3472
3529
|
if (services.includes("api")) {
|
|
3473
|
-
const { stopApiServer } = await import("./main-
|
|
3530
|
+
const { stopApiServer } = await import("./main-BAO4kKce.mjs");
|
|
3474
3531
|
await stopApiServer();
|
|
3475
3532
|
}
|
|
3476
3533
|
if (services.includes("delivery")) {
|
|
3477
|
-
const { stopDeliveryWorker } = await import("./main-
|
|
3534
|
+
const { stopDeliveryWorker } = await import("./main-7KMlWnDx.mjs");
|
|
3478
3535
|
await stopDeliveryWorker();
|
|
3479
3536
|
}
|
|
3480
3537
|
if (services.includes("engine")) {
|
|
3481
|
-
const { stopEngineWorker } = await import("./main-
|
|
3538
|
+
const { stopEngineWorker } = await import("./main-BxqAXTr6.mjs");
|
|
3482
3539
|
await stopEngineWorker();
|
|
3483
3540
|
}
|
|
3484
3541
|
if (services.includes("enricher")) {
|
|
3485
|
-
const { stopEnricherWorker } = await import("./main-
|
|
3542
|
+
const { stopEnricherWorker } = await import("./main-B0BcY_JJ.mjs");
|
|
3486
3543
|
await stopEnricherWorker();
|
|
3487
3544
|
}
|
|
3488
3545
|
if (services.includes("scheduler")) {
|
|
3489
|
-
const { stopSchedulerWorker } = await import("./main-
|
|
3546
|
+
const { stopSchedulerWorker } = await import("./main-zCpvA9Rx.mjs");
|
|
3490
3547
|
await stopSchedulerWorker();
|
|
3491
3548
|
}
|
|
3492
3549
|
if (services.includes("ai")) {
|
|
3493
|
-
const { stopAiWorker } = await import("./main-
|
|
3550
|
+
const { stopAiWorker } = await import("./main-0FHNtN5g.mjs");
|
|
3494
3551
|
await stopAiWorker();
|
|
3495
3552
|
}
|
|
3496
3553
|
if (services.includes("workflow")) {
|
|
3497
|
-
const { stopWorkflowWorker } = await import("./main-
|
|
3554
|
+
const { stopWorkflowWorker } = await import("./main-BtXITy0k.mjs");
|
|
3498
3555
|
await stopWorkflowWorker();
|
|
3499
3556
|
}
|
|
3500
3557
|
if (services.includes("events")) {
|
|
3501
|
-
const { stopEventWorker } = await import("./main-
|
|
3558
|
+
const { stopEventWorker } = await import("./main-BjXgGJBd.mjs");
|
|
3502
3559
|
await stopEventWorker();
|
|
3503
3560
|
}
|
|
3504
3561
|
if (this.pgContainer) {
|
|
@@ -3512,6 +3569,6 @@ var NotifkitServer = class extends EventEmitter {
|
|
|
3512
3569
|
}
|
|
3513
3570
|
};
|
|
3514
3571
|
//#endregion
|
|
3515
|
-
export {
|
|
3572
|
+
export { metrics as $, ENRICHED_STREAMS as $t, RedisClient as A, NotificationCreatedPayloadSchema as At, AsyncSemaphore as B, NotifyRequestSchema as Bt, PreferenceRepository as C, NotificationDeliveredPayloadSchema as Ct, UserRepository as D, NotificationScheduledPayloadSchema as Dt, TemplateRepository as E, RenderedContentSchema as Et, generateId as F, BatchAddContactsSchema as Ft, getPriorityBucket as G, TriggerWorkflowSchema as Gt, LUA_RENEW_LOCK as H, QuietHoursSchema as Ht, sleep as I, ContactChannelSchema as It, globalEmitter as J, UserContactInputSchema as Jt, normaliseTarget as K, UpdateProjectSchema as Kt, DataLoader as L, CreateWorkflowSchema as Lt, UserThrottle as M, NotificationTargetSchema as Mt, AppError as N, AddContactSchema as Nt, WorkflowRepository as O, NotificationEnrichedPayloadSchema as Ot, ValidationError as P, AddUserSchema as Pt, getMetricsRegistry as Q, CONSUMER_GROUPS as Qt, CircuitBreaker as R, IngestEventSchema as Rt, ContactRepository as S, NotificationFailedPayloadSchema as St, SegmentRepository as T, NotificationDispatchedPayloadSchema as Tt, LUA_SCHEDULER_CLAIM as U, SyncTemplatesSchema as Ut, LUA_RELEASE_LOCK as V, PreferencesSchema as Vt, LUA_SCHEDULER_POLL as W, TemplateSchema as Wt, StreamConsumer as X, WorkflowStepSchema as Xt, PendingMessageScanner as Y, WorkflowNotifyPayloadSchema as Yt, StreamProducer as Z, buildStreamEvent as Zt, escapeHeader as _, parseConfig as _n, workflowSteps as _t, SuspendExecutionError as a, StreamEventMetadataSchema as an, createDatabase as at, renderWithTemplate as b, setGlobalConfig as bn, NotificationCanceledPayloadSchema as bt, BaseWorker as c, registry as cn, messageLogs as ct, buildUnsubscribeHeaders as d, NotificationPrioritySchema as dn, scheduledPayloads as dt, INBOUND_STREAMS as en, childLogger as et, signUnsubscribeToken as f, NotificationStatusSchema as fn, suppressions as ft, TemplateCache as g, loadEnv as gn, workflowInstances as gt, templateRegistry as h, getAiConfig as hn, workflowDefinitions as ht, workflowRegistry as i, EventEnvelopeSchema as in, IdempotencyGuard as it, ProjectSettingsCache as j, NotificationRequestedPayloadSchema as jt, Redis as k, RecipientProfileSchema as kt, NonRetryableError as l, EventMetadataSchema as ln, projectApiKeys as lt, renderTemplate as m, baseConfigSchema as mn, users as mt, NotifkitClient as n, PUBSUB_CHANNELS as nn, withContext as nt, buildStepNotifyPayload as o, StreamEventSchema as on, runMigrations as ot, verifyUnsubscribeToken as p, AI_DEFAULTS as pn, userTopicPreferences as pt, LRUCache as q, UpdateUserSchema as qt, workflow as r, STREAMS as rn, withRequestId as rt, resolveStepTarget as s, EventRegistry as sn, deliveryOutbox as st, NotifkitServer as t, OUTBOUND_STREAMS as tn, createLogger as tt, startHealthReporter as u, NotificationChannelSchema as un, projects as ut, escapeHtml as v, readBaseConfig as vn, workflowWaiters as vt, ProjectRepository as w, DeliveryOptionsSchema as wt, AdminUserRepository as x, NotificationSkippedPayloadSchema as xt, interpolate as y, setAiConfig as yn, NotificationAiPendingPayloadSchema as yt, BatchProcessor as z, InlineUserSchema as zt };
|
|
3516
3573
|
|
|
3517
|
-
//# sourceMappingURL=src-
|
|
3574
|
+
//# sourceMappingURL=src-DkvHYM3y.mjs.map
|