fluxmail 0.1.0 → 0.2.1

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.
Files changed (73) hide show
  1. package/LICENSE.md +111 -0
  2. package/README.md +68 -0
  3. package/dist/accounts/gmailConnection.d.ts +17 -0
  4. package/dist/accounts/gmailConnection.d.ts.map +1 -0
  5. package/dist/accounts/gmailConnection.js +32 -0
  6. package/dist/accounts/gmailConnection.js.map +1 -0
  7. package/dist/accounts/googleAuth.js +7 -3
  8. package/dist/accounts/googleAuth.js.map +1 -1
  9. package/dist/accounts/registry.d.ts +11 -2
  10. package/dist/accounts/registry.d.ts.map +1 -1
  11. package/dist/accounts/registry.js +121 -28
  12. package/dist/accounts/registry.js.map +1 -1
  13. package/dist/cli.js +278 -15
  14. package/dist/cli.js.map +1 -1
  15. package/dist/config.d.ts +5 -1
  16. package/dist/config.d.ts.map +1 -1
  17. package/dist/config.js +20 -13
  18. package/dist/config.js.map +1 -1
  19. package/dist/context.d.ts +2 -0
  20. package/dist/context.d.ts.map +1 -1
  21. package/dist/context.js +3 -1
  22. package/dist/context.js.map +1 -1
  23. package/dist/http/app.d.ts +2 -0
  24. package/dist/http/app.d.ts.map +1 -1
  25. package/dist/http/app.js +96 -18
  26. package/dist/http/app.js.map +1 -1
  27. package/dist/index.d.ts +5 -4
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +4 -3
  30. package/dist/index.js.map +1 -1
  31. package/dist/licensing/activation.d.ts.map +1 -1
  32. package/dist/licensing/activation.js.map +1 -1
  33. package/dist/licensing/entitlements.d.ts.map +1 -1
  34. package/dist/licensing/entitlements.js.map +1 -1
  35. package/dist/licensing/lease.d.ts.map +1 -1
  36. package/dist/licensing/lease.js.map +1 -1
  37. package/dist/mcp/buildServer.d.ts +7 -1
  38. package/dist/mcp/buildServer.d.ts.map +1 -1
  39. package/dist/mcp/buildServer.js +108 -40
  40. package/dist/mcp/buildServer.js.map +1 -1
  41. package/dist/scheduler/sendScheduler.d.ts.map +1 -1
  42. package/dist/scheduler/sendScheduler.js +1 -3
  43. package/dist/scheduler/sendScheduler.js.map +1 -1
  44. package/dist/service/emailService.d.ts +1 -0
  45. package/dist/service/emailService.d.ts.map +1 -1
  46. package/dist/service/emailService.js +11 -6
  47. package/dist/service/emailService.js.map +1 -1
  48. package/dist/storage/apiKeys.d.ts.map +1 -1
  49. package/dist/storage/apiKeys.js +8 -2
  50. package/dist/storage/apiKeys.js.map +1 -1
  51. package/dist/storage/db.d.ts +446 -0
  52. package/dist/storage/db.d.ts.map +1 -1
  53. package/dist/storage/db.js +89 -0
  54. package/dist/storage/db.js.map +1 -1
  55. package/dist/storage/gmailConnectionGrants.d.ts +28 -0
  56. package/dist/storage/gmailConnectionGrants.d.ts.map +1 -0
  57. package/dist/storage/gmailConnectionGrants.js +70 -0
  58. package/dist/storage/gmailConnectionGrants.js.map +1 -0
  59. package/dist/storage/imapState.d.ts +15 -0
  60. package/dist/storage/imapState.d.ts.map +1 -0
  61. package/dist/storage/imapState.js +89 -0
  62. package/dist/storage/imapState.js.map +1 -0
  63. package/dist/storage/members.d.ts.map +1 -1
  64. package/dist/storage/members.js.map +1 -1
  65. package/dist/storage/scheduledSends.d.ts.map +1 -1
  66. package/dist/storage/scheduledSends.js.map +1 -1
  67. package/dist/telemetry.d.ts +28 -0
  68. package/dist/telemetry.d.ts.map +1 -0
  69. package/dist/telemetry.js +220 -0
  70. package/dist/telemetry.js.map +1 -0
  71. package/dist/version.d.ts.map +1 -1
  72. package/dist/version.js.map +1 -1
  73. package/package.json +22 -7
@@ -12,7 +12,9 @@ export function createApiKey(db, name, memberId) {
12
12
  const id = `key_${randomBytes(8).toString('hex')}`;
13
13
  const key = `fmk_${randomBytes(24).toString('hex')}`;
14
14
  const createdAt = Date.now();
15
- db.insert(apiKeys).values({ id, name, keyHash: hashKey(key), createdAt, memberId: memberId ?? null }).run();
15
+ db.insert(apiKeys)
16
+ .values({ id, name, keyHash: hashKey(key), createdAt, memberId: memberId ?? null })
17
+ .run();
16
18
  return { key, info: { id, name, createdAt, lastUsedAt: null, memberId: memberId ?? null } };
17
19
  }
18
20
  /**
@@ -20,7 +22,11 @@ export function createApiKey(db, name, memberId) {
20
22
  * honour `memberId`: a member-scoped key may only reach shared or owned mailboxes.
21
23
  */
22
24
  export function authenticateApiKey(db, key) {
23
- const row = db.select().from(apiKeys).where(eq(apiKeys.keyHash, hashKey(key))).get();
25
+ const row = db
26
+ .select()
27
+ .from(apiKeys)
28
+ .where(eq(apiKeys.keyHash, hashKey(key)))
29
+ .get();
24
30
  if (!row)
25
31
  return null;
26
32
  db.update(apiKeys).set({ lastUsedAt: Date.now() }).where(eq(apiKeys.id, row.id)).run();
@@ -1 +1 @@
1
- {"version":3,"file":"apiKeys.js","sourceRoot":"","sources":["../../src/storage/apiKeys.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"apiKeys.js","sourceRoot":"","sources":["../../src/storage/apiKeys.ts"],"names":[],"mappings":"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"}
@@ -280,6 +280,318 @@ export declare const oauthTokens: import("drizzle-orm/sqlite-core").SQLiteTableW
280
280
  };
281
281
  dialect: "sqlite";
282
282
  }>;
283
+ export declare const accountCredentials: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
284
+ name: "account_credentials";
285
+ schema: undefined;
286
+ columns: {
287
+ accountId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
288
+ name: "account_id";
289
+ tableName: "account_credentials";
290
+ dataType: "string";
291
+ columnType: "SQLiteText";
292
+ data: string;
293
+ driverParam: string;
294
+ notNull: true;
295
+ hasDefault: false;
296
+ isPrimaryKey: true;
297
+ isAutoincrement: false;
298
+ hasRuntimeDefault: false;
299
+ enumValues: [string, ...string[]];
300
+ baseColumn: never;
301
+ identity: undefined;
302
+ generated: undefined;
303
+ }, {}, {
304
+ length: number | undefined;
305
+ }>;
306
+ encryptedCredentials: import("drizzle-orm/sqlite-core").SQLiteColumn<{
307
+ name: "encrypted_credentials";
308
+ tableName: "account_credentials";
309
+ dataType: "string";
310
+ columnType: "SQLiteText";
311
+ data: string;
312
+ driverParam: string;
313
+ notNull: true;
314
+ hasDefault: false;
315
+ isPrimaryKey: false;
316
+ isAutoincrement: false;
317
+ hasRuntimeDefault: false;
318
+ enumValues: [string, ...string[]];
319
+ baseColumn: never;
320
+ identity: undefined;
321
+ generated: undefined;
322
+ }, {}, {
323
+ length: number | undefined;
324
+ }>;
325
+ updatedAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
326
+ name: "updated_at";
327
+ tableName: "account_credentials";
328
+ dataType: "number";
329
+ columnType: "SQLiteInteger";
330
+ data: number;
331
+ driverParam: number;
332
+ notNull: true;
333
+ hasDefault: false;
334
+ isPrimaryKey: false;
335
+ isAutoincrement: false;
336
+ hasRuntimeDefault: false;
337
+ enumValues: undefined;
338
+ baseColumn: never;
339
+ identity: undefined;
340
+ generated: undefined;
341
+ }, {}, {}>;
342
+ };
343
+ dialect: "sqlite";
344
+ }>;
345
+ export declare const imapMessages: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
346
+ name: "imap_messages";
347
+ schema: undefined;
348
+ columns: {
349
+ id: import("drizzle-orm/sqlite-core").SQLiteColumn<{
350
+ name: "id";
351
+ tableName: "imap_messages";
352
+ dataType: "string";
353
+ columnType: "SQLiteText";
354
+ data: string;
355
+ driverParam: string;
356
+ notNull: true;
357
+ hasDefault: false;
358
+ isPrimaryKey: true;
359
+ isAutoincrement: false;
360
+ hasRuntimeDefault: false;
361
+ enumValues: [string, ...string[]];
362
+ baseColumn: never;
363
+ identity: undefined;
364
+ generated: undefined;
365
+ }, {}, {
366
+ length: number | undefined;
367
+ }>;
368
+ accountId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
369
+ name: "account_id";
370
+ tableName: "imap_messages";
371
+ dataType: "string";
372
+ columnType: "SQLiteText";
373
+ data: string;
374
+ driverParam: string;
375
+ notNull: true;
376
+ hasDefault: false;
377
+ isPrimaryKey: false;
378
+ isAutoincrement: false;
379
+ hasRuntimeDefault: false;
380
+ enumValues: [string, ...string[]];
381
+ baseColumn: never;
382
+ identity: undefined;
383
+ generated: undefined;
384
+ }, {}, {
385
+ length: number | undefined;
386
+ }>;
387
+ mailboxPath: import("drizzle-orm/sqlite-core").SQLiteColumn<{
388
+ name: "mailbox_path";
389
+ tableName: "imap_messages";
390
+ dataType: "string";
391
+ columnType: "SQLiteText";
392
+ data: string;
393
+ driverParam: string;
394
+ notNull: true;
395
+ hasDefault: false;
396
+ isPrimaryKey: false;
397
+ isAutoincrement: false;
398
+ hasRuntimeDefault: false;
399
+ enumValues: [string, ...string[]];
400
+ baseColumn: never;
401
+ identity: undefined;
402
+ generated: undefined;
403
+ }, {}, {
404
+ length: number | undefined;
405
+ }>;
406
+ uidValidity: import("drizzle-orm/sqlite-core").SQLiteColumn<{
407
+ name: "uid_validity";
408
+ tableName: "imap_messages";
409
+ dataType: "string";
410
+ columnType: "SQLiteText";
411
+ data: string;
412
+ driverParam: string;
413
+ notNull: true;
414
+ hasDefault: false;
415
+ isPrimaryKey: false;
416
+ isAutoincrement: false;
417
+ hasRuntimeDefault: false;
418
+ enumValues: [string, ...string[]];
419
+ baseColumn: never;
420
+ identity: undefined;
421
+ generated: undefined;
422
+ }, {}, {
423
+ length: number | undefined;
424
+ }>;
425
+ uid: import("drizzle-orm/sqlite-core").SQLiteColumn<{
426
+ name: "uid";
427
+ tableName: "imap_messages";
428
+ dataType: "number";
429
+ columnType: "SQLiteInteger";
430
+ data: number;
431
+ driverParam: number;
432
+ notNull: true;
433
+ hasDefault: false;
434
+ isPrimaryKey: false;
435
+ isAutoincrement: false;
436
+ hasRuntimeDefault: false;
437
+ enumValues: undefined;
438
+ baseColumn: never;
439
+ identity: undefined;
440
+ generated: undefined;
441
+ }, {}, {}>;
442
+ messageId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
443
+ name: "message_id";
444
+ tableName: "imap_messages";
445
+ dataType: "string";
446
+ columnType: "SQLiteText";
447
+ data: string;
448
+ driverParam: string;
449
+ notNull: false;
450
+ hasDefault: false;
451
+ isPrimaryKey: false;
452
+ isAutoincrement: false;
453
+ hasRuntimeDefault: false;
454
+ enumValues: [string, ...string[]];
455
+ baseColumn: never;
456
+ identity: undefined;
457
+ generated: undefined;
458
+ }, {}, {
459
+ length: number | undefined;
460
+ }>;
461
+ inReplyTo: import("drizzle-orm/sqlite-core").SQLiteColumn<{
462
+ name: "in_reply_to";
463
+ tableName: "imap_messages";
464
+ dataType: "string";
465
+ columnType: "SQLiteText";
466
+ data: string;
467
+ driverParam: string;
468
+ notNull: false;
469
+ hasDefault: false;
470
+ isPrimaryKey: false;
471
+ isAutoincrement: false;
472
+ hasRuntimeDefault: false;
473
+ enumValues: [string, ...string[]];
474
+ baseColumn: never;
475
+ identity: undefined;
476
+ generated: undefined;
477
+ }, {}, {
478
+ length: number | undefined;
479
+ }>;
480
+ references: import("drizzle-orm/sqlite-core").SQLiteColumn<{
481
+ name: "reference_ids";
482
+ tableName: "imap_messages";
483
+ dataType: "string";
484
+ columnType: "SQLiteText";
485
+ data: string;
486
+ driverParam: string;
487
+ notNull: false;
488
+ hasDefault: false;
489
+ isPrimaryKey: false;
490
+ isAutoincrement: false;
491
+ hasRuntimeDefault: false;
492
+ enumValues: [string, ...string[]];
493
+ baseColumn: never;
494
+ identity: undefined;
495
+ generated: undefined;
496
+ }, {}, {
497
+ length: number | undefined;
498
+ }>;
499
+ threadId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
500
+ name: "thread_id";
501
+ tableName: "imap_messages";
502
+ dataType: "string";
503
+ columnType: "SQLiteText";
504
+ data: string;
505
+ driverParam: string;
506
+ notNull: true;
507
+ hasDefault: false;
508
+ isPrimaryKey: false;
509
+ isAutoincrement: false;
510
+ hasRuntimeDefault: false;
511
+ enumValues: [string, ...string[]];
512
+ baseColumn: never;
513
+ identity: undefined;
514
+ generated: undefined;
515
+ }, {}, {
516
+ length: number | undefined;
517
+ }>;
518
+ draftId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
519
+ name: "draft_id";
520
+ tableName: "imap_messages";
521
+ dataType: "string";
522
+ columnType: "SQLiteText";
523
+ data: string;
524
+ driverParam: string;
525
+ notNull: false;
526
+ hasDefault: false;
527
+ isPrimaryKey: false;
528
+ isAutoincrement: false;
529
+ hasRuntimeDefault: false;
530
+ enumValues: [string, ...string[]];
531
+ baseColumn: never;
532
+ identity: undefined;
533
+ generated: undefined;
534
+ }, {}, {
535
+ length: number | undefined;
536
+ }>;
537
+ subject: import("drizzle-orm/sqlite-core").SQLiteColumn<{
538
+ name: "subject";
539
+ tableName: "imap_messages";
540
+ dataType: "string";
541
+ columnType: "SQLiteText";
542
+ data: string;
543
+ driverParam: string;
544
+ notNull: false;
545
+ hasDefault: false;
546
+ isPrimaryKey: false;
547
+ isAutoincrement: false;
548
+ hasRuntimeDefault: false;
549
+ enumValues: [string, ...string[]];
550
+ baseColumn: never;
551
+ identity: undefined;
552
+ generated: undefined;
553
+ }, {}, {
554
+ length: number | undefined;
555
+ }>;
556
+ date: import("drizzle-orm/sqlite-core").SQLiteColumn<{
557
+ name: "date";
558
+ tableName: "imap_messages";
559
+ dataType: "string";
560
+ columnType: "SQLiteText";
561
+ data: string;
562
+ driverParam: string;
563
+ notNull: false;
564
+ hasDefault: false;
565
+ isPrimaryKey: false;
566
+ isAutoincrement: false;
567
+ hasRuntimeDefault: false;
568
+ enumValues: [string, ...string[]];
569
+ baseColumn: never;
570
+ identity: undefined;
571
+ generated: undefined;
572
+ }, {}, {
573
+ length: number | undefined;
574
+ }>;
575
+ updatedAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
576
+ name: "updated_at";
577
+ tableName: "imap_messages";
578
+ dataType: "number";
579
+ columnType: "SQLiteInteger";
580
+ data: number;
581
+ driverParam: number;
582
+ notNull: true;
583
+ hasDefault: false;
584
+ isPrimaryKey: false;
585
+ isAutoincrement: false;
586
+ hasRuntimeDefault: false;
587
+ enumValues: undefined;
588
+ baseColumn: never;
589
+ identity: undefined;
590
+ generated: undefined;
591
+ }, {}, {}>;
592
+ };
593
+ dialect: "sqlite";
594
+ }>;
283
595
  export declare const apiKeys: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
284
596
  name: "api_keys";
285
597
  schema: undefined;
@@ -397,6 +709,140 @@ export declare const apiKeys: import("drizzle-orm/sqlite-core").SQLiteTableWithC
397
709
  };
398
710
  dialect: "sqlite";
399
711
  }>;
712
+ export declare const gmailConnectionGrants: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
713
+ name: "gmail_connection_grants";
714
+ schema: undefined;
715
+ columns: {
716
+ tokenHash: import("drizzle-orm/sqlite-core").SQLiteColumn<{
717
+ name: "token_hash";
718
+ tableName: "gmail_connection_grants";
719
+ dataType: "string";
720
+ columnType: "SQLiteText";
721
+ data: string;
722
+ driverParam: string;
723
+ notNull: true;
724
+ hasDefault: false;
725
+ isPrimaryKey: true;
726
+ isAutoincrement: false;
727
+ hasRuntimeDefault: false;
728
+ enumValues: [string, ...string[]];
729
+ baseColumn: never;
730
+ identity: undefined;
731
+ generated: undefined;
732
+ }, {}, {
733
+ length: number | undefined;
734
+ }>;
735
+ scope: import("drizzle-orm/sqlite-core").SQLiteColumn<{
736
+ name: "scope";
737
+ tableName: "gmail_connection_grants";
738
+ dataType: "string";
739
+ columnType: "SQLiteText";
740
+ data: string;
741
+ driverParam: string;
742
+ notNull: true;
743
+ hasDefault: false;
744
+ isPrimaryKey: false;
745
+ isAutoincrement: false;
746
+ hasRuntimeDefault: false;
747
+ enumValues: [string, ...string[]];
748
+ baseColumn: never;
749
+ identity: undefined;
750
+ generated: undefined;
751
+ }, {}, {
752
+ length: number | undefined;
753
+ }>;
754
+ memberId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
755
+ name: "member_id";
756
+ tableName: "gmail_connection_grants";
757
+ dataType: "string";
758
+ columnType: "SQLiteText";
759
+ data: string;
760
+ driverParam: string;
761
+ notNull: false;
762
+ hasDefault: false;
763
+ isPrimaryKey: false;
764
+ isAutoincrement: false;
765
+ hasRuntimeDefault: false;
766
+ enumValues: [string, ...string[]];
767
+ baseColumn: never;
768
+ identity: undefined;
769
+ generated: undefined;
770
+ }, {}, {
771
+ length: number | undefined;
772
+ }>;
773
+ reauthorizeAccountId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
774
+ name: "reauthorize_account_id";
775
+ tableName: "gmail_connection_grants";
776
+ dataType: "string";
777
+ columnType: "SQLiteText";
778
+ data: string;
779
+ driverParam: string;
780
+ notNull: false;
781
+ hasDefault: false;
782
+ isPrimaryKey: false;
783
+ isAutoincrement: false;
784
+ hasRuntimeDefault: false;
785
+ enumValues: [string, ...string[]];
786
+ baseColumn: never;
787
+ identity: undefined;
788
+ generated: undefined;
789
+ }, {}, {
790
+ length: number | undefined;
791
+ }>;
792
+ createdAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
793
+ name: "created_at";
794
+ tableName: "gmail_connection_grants";
795
+ dataType: "number";
796
+ columnType: "SQLiteInteger";
797
+ data: number;
798
+ driverParam: number;
799
+ notNull: true;
800
+ hasDefault: false;
801
+ isPrimaryKey: false;
802
+ isAutoincrement: false;
803
+ hasRuntimeDefault: false;
804
+ enumValues: undefined;
805
+ baseColumn: never;
806
+ identity: undefined;
807
+ generated: undefined;
808
+ }, {}, {}>;
809
+ expiresAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
810
+ name: "expires_at";
811
+ tableName: "gmail_connection_grants";
812
+ dataType: "number";
813
+ columnType: "SQLiteInteger";
814
+ data: number;
815
+ driverParam: number;
816
+ notNull: true;
817
+ hasDefault: false;
818
+ isPrimaryKey: false;
819
+ isAutoincrement: false;
820
+ hasRuntimeDefault: false;
821
+ enumValues: undefined;
822
+ baseColumn: never;
823
+ identity: undefined;
824
+ generated: undefined;
825
+ }, {}, {}>;
826
+ consumedAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
827
+ name: "consumed_at";
828
+ tableName: "gmail_connection_grants";
829
+ dataType: "number";
830
+ columnType: "SQLiteInteger";
831
+ data: number;
832
+ driverParam: number;
833
+ notNull: false;
834
+ hasDefault: false;
835
+ isPrimaryKey: false;
836
+ isAutoincrement: false;
837
+ hasRuntimeDefault: false;
838
+ enumValues: undefined;
839
+ baseColumn: never;
840
+ identity: undefined;
841
+ generated: undefined;
842
+ }, {}, {}>;
843
+ };
844
+ dialect: "sqlite";
845
+ }>;
400
846
  export declare const licenseLease: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
401
847
  name: "license_lease";
402
848
  schema: undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/storage/db.ts"],"names":[],"mappings":"AACA,OAAO,EAAW,KAAK,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAGjF,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASnB,CAAC;AAEF,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAapB,CAAC;AAEF,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAOtB,CAAC;AAEH,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASlB,CAAC;AAEH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAMvB,CAAC;AAEH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuB1B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,qBAAqB,CAAC;AAiE/C,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAgBjD"}
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/storage/db.ts"],"names":[],"mappings":"AACA,OAAO,EAAW,KAAK,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAGjF,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASnB,CAAC;AAEF,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAapB,CAAC;AAEF,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAOtB,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAO7B,CAAC;AAEH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyBxB,CAAC;AAEF,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASlB,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAShC,CAAC;AAEH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAMvB,CAAC;AAEH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuB1B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,qBAAqB,CAAC;AAwG/C,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CA0BjD"}
@@ -25,6 +25,36 @@ export const oauthTokens = sqliteTable('oauth_tokens', {
25
25
  encryptedTokens: text('encrypted_tokens').notNull(),
26
26
  updatedAt: integer('updated_at').notNull(),
27
27
  });
28
+ export const accountCredentials = sqliteTable('account_credentials', {
29
+ accountId: text('account_id')
30
+ .primaryKey()
31
+ .references(() => accounts.id, { onDelete: 'cascade' }),
32
+ /** AES-256-GCM encrypted provider-specific credentials. */
33
+ encryptedCredentials: text('encrypted_credentials').notNull(),
34
+ updatedAt: integer('updated_at').notNull(),
35
+ });
36
+ export const imapMessages = sqliteTable('imap_messages', {
37
+ id: text('id').primaryKey(),
38
+ accountId: text('account_id')
39
+ .notNull()
40
+ .references(() => accounts.id, { onDelete: 'cascade' }),
41
+ mailboxPath: text('mailbox_path').notNull(),
42
+ uidValidity: text('uid_validity').notNull(),
43
+ uid: integer('uid').notNull(),
44
+ messageId: text('message_id'),
45
+ inReplyTo: text('in_reply_to'),
46
+ references: text('reference_ids'),
47
+ threadId: text('thread_id').notNull(),
48
+ draftId: text('draft_id'),
49
+ subject: text('subject'),
50
+ date: text('date'),
51
+ updatedAt: integer('updated_at').notNull(),
52
+ }, (table) => [
53
+ uniqueIndex('imap_messages_location_unique').on(table.accountId, table.mailboxPath, table.uidValidity, table.uid),
54
+ index('imap_messages_message_id').on(table.accountId, table.messageId),
55
+ index('imap_messages_thread_id').on(table.accountId, table.threadId),
56
+ uniqueIndex('imap_messages_draft_id_unique').on(table.accountId, table.draftId),
57
+ ]);
28
58
  export const apiKeys = sqliteTable('api_keys', {
29
59
  id: text('id').primaryKey(),
30
60
  name: text('name').notNull(),
@@ -35,6 +65,16 @@ export const apiKeys = sqliteTable('api_keys', {
35
65
  /** Member the key was issued to; NULL means an unscoped admin key. */
36
66
  memberId: text('member_id').references(() => members.id, { onDelete: 'set null' }),
37
67
  });
68
+ export const gmailConnectionGrants = sqliteTable('gmail_connection_grants', {
69
+ /** SHA-256 hex digest. The raw token is printed once and never stored. */
70
+ tokenHash: text('token_hash').primaryKey(),
71
+ scope: text('scope').notNull(),
72
+ memberId: text('member_id'),
73
+ reauthorizeAccountId: text('reauthorize_account_id'),
74
+ createdAt: integer('created_at').notNull(),
75
+ expiresAt: integer('expires_at').notNull(),
76
+ consumedAt: integer('consumed_at'),
77
+ });
38
78
  export const licenseLease = sqliteTable('license_lease', {
39
79
  /** Single-row table; the row id is always 'current'. */
40
80
  id: text('id').primaryKey(),
@@ -86,6 +126,34 @@ CREATE TABLE IF NOT EXISTS oauth_tokens (
86
126
  encrypted_tokens TEXT NOT NULL,
87
127
  updated_at INTEGER NOT NULL
88
128
  );
129
+ CREATE TABLE IF NOT EXISTS account_credentials (
130
+ account_id TEXT PRIMARY KEY REFERENCES accounts(id) ON DELETE CASCADE,
131
+ encrypted_credentials TEXT NOT NULL,
132
+ updated_at INTEGER NOT NULL
133
+ );
134
+ CREATE TABLE IF NOT EXISTS imap_messages (
135
+ id TEXT PRIMARY KEY,
136
+ account_id TEXT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
137
+ mailbox_path TEXT NOT NULL,
138
+ uid_validity TEXT NOT NULL,
139
+ uid INTEGER NOT NULL,
140
+ message_id TEXT,
141
+ in_reply_to TEXT,
142
+ reference_ids TEXT,
143
+ thread_id TEXT NOT NULL,
144
+ draft_id TEXT,
145
+ subject TEXT,
146
+ date TEXT,
147
+ updated_at INTEGER NOT NULL
148
+ );
149
+ CREATE UNIQUE INDEX IF NOT EXISTS imap_messages_location_unique
150
+ ON imap_messages(account_id, mailbox_path, uid_validity, uid);
151
+ CREATE INDEX IF NOT EXISTS imap_messages_message_id
152
+ ON imap_messages(account_id, message_id);
153
+ CREATE INDEX IF NOT EXISTS imap_messages_thread_id
154
+ ON imap_messages(account_id, thread_id);
155
+ CREATE UNIQUE INDEX IF NOT EXISTS imap_messages_draft_id_unique
156
+ ON imap_messages(account_id, draft_id);
89
157
  CREATE TABLE IF NOT EXISTS api_keys (
90
158
  id TEXT PRIMARY KEY,
91
159
  name TEXT NOT NULL,
@@ -94,6 +162,17 @@ CREATE TABLE IF NOT EXISTS api_keys (
94
162
  last_used_at INTEGER,
95
163
  member_id TEXT REFERENCES members(id) ON DELETE SET NULL
96
164
  );
165
+ CREATE TABLE IF NOT EXISTS gmail_connection_grants (
166
+ token_hash TEXT PRIMARY KEY,
167
+ scope TEXT NOT NULL,
168
+ member_id TEXT,
169
+ reauthorize_account_id TEXT,
170
+ created_at INTEGER NOT NULL,
171
+ expires_at INTEGER NOT NULL,
172
+ consumed_at INTEGER
173
+ );
174
+ CREATE INDEX IF NOT EXISTS gmail_connection_grants_expires_at
175
+ ON gmail_connection_grants(expires_at);
97
176
  CREATE TABLE IF NOT EXISTS license_lease (
98
177
  id TEXT PRIMARY KEY,
99
178
  token TEXT NOT NULL,
@@ -126,6 +205,16 @@ export function openDb(dbPath) {
126
205
  sqlite.pragma('journal_mode = WAL');
127
206
  sqlite.pragma('foreign_keys = ON');
128
207
  sqlite.exec(BOOTSTRAP_SQL);
208
+ // Keep the generic credential row in sync if an older binary updated the
209
+ // legacy Gmail token table before this version reopened the database.
210
+ sqlite.exec(`
211
+ INSERT INTO account_credentials (account_id, encrypted_credentials, updated_at)
212
+ SELECT account_id, encrypted_tokens, updated_at FROM oauth_tokens WHERE true
213
+ ON CONFLICT(account_id) DO UPDATE SET
214
+ encrypted_credentials = excluded.encrypted_credentials,
215
+ updated_at = excluded.updated_at
216
+ WHERE excluded.updated_at > account_credentials.updated_at
217
+ `);
129
218
  const scheduledCols = tableColumns(sqlite, 'scheduled_sends');
130
219
  if (!scheduledCols.has('claim_token'))
131
220
  sqlite.exec('ALTER TABLE scheduled_sends ADD COLUMN claim_token TEXT');
@@ -1 +1 @@
1
- {"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/storage/db.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/storage/db.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { type FluxmailDb } from './db.js';
2
+ export declare const GMAIL_CONNECTION_GRANT_TTL_MS: number;
3
+ export interface GmailConnectionIntent {
4
+ memberId?: string;
5
+ reauthorizeAccountId?: string;
6
+ }
7
+ export interface GmailConnectionGrant extends GmailConnectionIntent {
8
+ expiresAt: number;
9
+ }
10
+ export type GmailConnectionClaim = {
11
+ status: 'claimed';
12
+ grant: GmailConnectionGrant;
13
+ } | {
14
+ status: 'invalid';
15
+ } | {
16
+ status: 'expired';
17
+ } | {
18
+ status: 'used';
19
+ };
20
+ export type GmailConnectionGrantStatus = 'available' | 'invalid' | 'expired' | 'used';
21
+ export declare function gmailConnectionTokenHash(token: string): string;
22
+ export declare function inspectGmailConnectionGrant(db: FluxmailDb, token: string, now?: number): GmailConnectionGrantStatus;
23
+ export declare function createGmailConnectionGrant(db: FluxmailDb, intent?: GmailConnectionIntent, now?: number): {
24
+ token: string;
25
+ expiresAt: number;
26
+ };
27
+ export declare function claimGmailConnectionGrant(db: FluxmailDb, token: string, now?: number): GmailConnectionClaim;
28
+ //# sourceMappingURL=gmailConnectionGrants.d.ts.map