@ibgib/node-gib 0.0.22 → 0.0.24

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 (81) hide show
  1. package/README.md +4 -0
  2. package/dist/email/aws/email-receiver-aws.mjs +3 -3
  3. package/dist/email/aws/email-receiver-aws.mjs.map +1 -1
  4. package/dist/email/aws/email-sender-aws.mjs +1 -1
  5. package/dist/email/aws/email-sender-aws.mjs.map +1 -1
  6. package/dist/email/email-sender.mjs +3 -3
  7. package/dist/email/email-sender.mjs.map +1 -1
  8. package/dist/email/verify/email-verify-helpers.mjs +5 -5
  9. package/dist/email/verify/email-verify-helpers.mjs.map +1 -1
  10. package/dist/identity/sso/custodian-auth-helpers.mjs +1 -1
  11. package/dist/identity/sso/custodian-auth-helpers.mjs.map +1 -1
  12. package/dist/identity/sso/sso-custodian-service.mjs +4 -4
  13. package/dist/identity/sso/sso-custodian-service.mjs.map +1 -1
  14. package/dist/serve-gib/handlers/api/email/email-inbound.handler.mjs +2 -2
  15. package/dist/serve-gib/handlers/api/email/email-inbound.handler.mjs.map +1 -1
  16. package/dist/serve-gib/handlers/api/email/email-outbound.handler.mjs +3 -3
  17. package/dist/serve-gib/handlers/api/email/email-outbound.handler.mjs.map +1 -1
  18. package/dist/serve-gib/handlers/api/email/email-verification-code.handler.mjs +1 -1
  19. package/dist/serve-gib/handlers/api/email/email-verification-code.handler.mjs.map +1 -1
  20. package/dist/serve-gib/handlers/api/email/email-verify-code-onetime.handler.mjs +1 -1
  21. package/dist/serve-gib/handlers/api/email/email-verify-code-onetime.handler.mjs.map +1 -1
  22. package/dist/serve-gib/handlers/api/identity/keystone-custodian-add-master-password.handler.mjs +15 -15
  23. package/dist/serve-gib/handlers/api/identity/keystone-custodian-add-master-password.handler.mjs.map +1 -1
  24. package/dist/serve-gib/handlers/api/identity/keystone-custodian-genesis.handler.mjs +2 -2
  25. package/dist/serve-gib/handlers/api/identity/keystone-custodian-genesis.handler.mjs.map +1 -1
  26. package/dist/serve-gib/handlers/api/identity/keystone-custodian-register-delegate.handler.mjs +1 -1
  27. package/dist/serve-gib/handlers/api/identity/keystone-custodian-register-delegate.handler.mjs.map +1 -1
  28. package/dist/serve-gib/handlers/api/keystone/keystone-genesis.handler.mjs +2 -2
  29. package/dist/serve-gib/handlers/api/keystone/keystone-genesis.handler.mjs.map +1 -1
  30. package/dist/serve-gib/handlers/api/keystone/keystone-lookup.handler.mjs +1 -1
  31. package/dist/serve-gib/handlers/api/keystone/keystone-lookup.handler.mjs.map +1 -1
  32. package/dist/serve-gib/handlers/api/keystone/sso-link.handler.mjs +6 -6
  33. package/dist/serve-gib/handlers/api/keystone/sso-link.handler.mjs.map +1 -1
  34. package/dist/serve-gib/handlers/api/keystone/sso-login.handler.mjs +3 -3
  35. package/dist/serve-gib/handlers/api/keystone/sso-login.handler.mjs.map +1 -1
  36. package/dist/serve-gib/identity-index/identity-index-helpers.mjs +1 -1
  37. package/dist/serve-gib/identity-index/identity-index-helpers.mjs.map +1 -1
  38. package/dist/serve-gib/identity-index/identity-index-service.mjs +1 -1
  39. package/dist/serve-gib/identity-index/identity-index-service.mjs.map +1 -1
  40. package/dist/vcs/workspace-space-helper.d.mts +26 -0
  41. package/dist/vcs/workspace-space-helper.d.mts.map +1 -0
  42. package/dist/vcs/workspace-space-helper.mjs +71 -0
  43. package/dist/vcs/workspace-space-helper.mjs.map +1 -0
  44. package/dist/witness/space/node-workspace-projection-space/node-workspace-projection-space-constants.d.mts +7 -0
  45. package/dist/witness/space/node-workspace-projection-space/node-workspace-projection-space-constants.d.mts.map +1 -0
  46. package/dist/witness/space/node-workspace-projection-space/node-workspace-projection-space-constants.mjs +7 -0
  47. package/dist/witness/space/node-workspace-projection-space/node-workspace-projection-space-constants.mjs.map +1 -0
  48. package/dist/witness/space/node-workspace-projection-space/node-workspace-projection-space-types.d.mts +15 -0
  49. package/dist/witness/space/node-workspace-projection-space/node-workspace-projection-space-types.d.mts.map +1 -0
  50. package/dist/witness/space/node-workspace-projection-space/node-workspace-projection-space-types.mjs +23 -0
  51. package/dist/witness/space/node-workspace-projection-space/node-workspace-projection-space-types.mjs.map +1 -0
  52. package/dist/witness/space/node-workspace-projection-space/node-workspace-projection-space-v1.d.mts +66 -0
  53. package/dist/witness/space/node-workspace-projection-space/node-workspace-projection-space-v1.d.mts.map +1 -0
  54. package/dist/witness/space/node-workspace-projection-space/node-workspace-projection-space-v1.mjs +326 -0
  55. package/dist/witness/space/node-workspace-projection-space/node-workspace-projection-space-v1.mjs.map +1 -0
  56. package/package.json +5 -5
  57. package/src/email/aws/email-receiver-aws.mts +3 -3
  58. package/src/email/aws/email-sender-aws.mts +1 -1
  59. package/src/email/email-sender.mts +3 -3
  60. package/src/email/verify/email-verify-helpers.mts +5 -5
  61. package/src/identity/sso/custodian-auth-helpers.mts +1 -1
  62. package/src/identity/sso/sso-custodian-service.mts +4 -4
  63. package/src/serve-gib/handlers/api/email/email-inbound.handler.mts +2 -2
  64. package/src/serve-gib/handlers/api/email/email-outbound.handler.mts +3 -3
  65. package/src/serve-gib/handlers/api/email/email-verification-code.handler.mts +1 -1
  66. package/src/serve-gib/handlers/api/email/email-verify-code-onetime.handler.mts +1 -1
  67. package/src/serve-gib/handlers/api/email/email-verify.respec.mts +4 -4
  68. package/src/serve-gib/handlers/api/identity/keystone-custodian-add-master-password.handler.mts +15 -15
  69. package/src/serve-gib/handlers/api/identity/keystone-custodian-genesis.handler.mts +2 -2
  70. package/src/serve-gib/handlers/api/identity/keystone-custodian-register-delegate.handler.mts +1 -1
  71. package/src/serve-gib/handlers/api/keystone/keystone-genesis.handler.mts +2 -2
  72. package/src/serve-gib/handlers/api/keystone/keystone-lookup.handler.mts +1 -1
  73. package/src/serve-gib/handlers/api/keystone/sso-link.handler.mts +6 -6
  74. package/src/serve-gib/handlers/api/keystone/sso-login.handler.mts +3 -3
  75. package/src/serve-gib/identity-index/identity-index-helpers.mts +1 -1
  76. package/src/serve-gib/identity-index/identity-index-service.mts +1 -1
  77. package/src/vcs/workspace-space-helper.mts +104 -0
  78. package/src/witness/space/node-workspace-projection-space/node-workspace-projection-space-constants.mts +8 -0
  79. package/src/witness/space/node-workspace-projection-space/node-workspace-projection-space-types.mts +43 -0
  80. package/src/witness/space/node-workspace-projection-space/node-workspace-projection-space-v1.mts +416 -0
  81. package/src/witness/space/node-workspace-projection-space/node-workspace-projection-space-v1.respec.mts +212 -0
@@ -14,16 +14,16 @@ export abstract class EmailSenderBase implements EmailSender {
14
14
  */
15
15
  protected validateOutboundEmail(email: OutboundEmail): void {
16
16
  if (!email) {
17
- throw new Error('OutboundEmail is required. (E: 8f4e2a1b9c3d4e5f6a7b8c9d0e1f2a3b)');
17
+ throw new Error('OutboundEmail is required. (E: genuuid)');
18
18
  }
19
19
 
20
20
  const fromParsed = parseEmailAddress(email.from);
21
21
  if (!fromParsed.address || !validateEmail(fromParsed.address)) {
22
- throw new Error(`Invalid "from" email address: ${fromParsed.address} (E: a1b2c3d4e5f67890123456789abcdef0)`);
22
+ throw new Error(`Invalid "from" email address: ${fromParsed.address} (E: genuuid)`);
23
23
  }
24
24
 
25
25
  if (!email.to || !Array.isArray(email.to) || email.to.length === 0) {
26
- throw new Error('Outbound email must contain at least one recipient in "to". (E: 1a2b3c4d5e6f7890123456789abcdef1)');
26
+ throw new Error('Outbound email must contain at least one recipient in "to". (E: genuuid)');
27
27
  }
28
28
 
29
29
  for (const recipient of email.to) {
@@ -33,7 +33,7 @@ export function createMagicLinkToken({
33
33
  nonce,
34
34
  }: CreateMagicLinkTokenOptions): string {
35
35
  if (!email || !validateEmail(email)) {
36
- throw new Error(`Invalid email address provided for magic link token creation: ${email} (E: a9b8c7d6e5f43210123456789abcdef0)`);
36
+ throw new Error(`Invalid email address provided for magic link token creation: ${email} (E: genuuid)`);
37
37
  }
38
38
  if (!primaryTjpAddr) {
39
39
  throw new Error(`primaryTjpAddr is required for magic link token creation (E: b8c7d6e5f43210123456789abcdef01)`);
@@ -282,7 +282,7 @@ export async function savePendingCodeRecord({
282
282
  export function createDefaultEmailSender(): EmailSender {
283
283
  const rawMode = process.env.EMAIL_MODE;
284
284
  if (!rawMode || !rawMode.trim()) {
285
- throw new Error('EMAIL_MODE environment variable is missing. Expected "aws" or "mock". (E: 7a8b9c0d1e2f3456789abcdef0123456)');
285
+ throw new Error('EMAIL_MODE environment variable is missing. Expected "aws" or "mock". (E: genuuid)');
286
286
  }
287
287
 
288
288
  const mode = rawMode.trim().toLowerCase();
@@ -292,7 +292,7 @@ export function createDefaultEmailSender(): EmailSender {
292
292
  const accessKeyId = process.env.AWS_ACCESS_KEY_ID;
293
293
  const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
294
294
  if (!accessKeyId || !secretAccessKey) {
295
- throw new Error('EMAIL_MODE=aws requires AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables. (E: 5e6f7890123456789abcdef5a6b7c8d9)');
295
+ throw new Error('EMAIL_MODE=aws requires AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables. (E: genuuid)');
296
296
  }
297
297
  return new EmailSenderAws({
298
298
  accessKeyId,
@@ -301,11 +301,11 @@ export function createDefaultEmailSender(): EmailSender {
301
301
  });
302
302
  } else if (mode === 'mock') {
303
303
  if (isProd) {
304
- throw new Error('EMAIL_MODE=mock is prohibited when NODE_ENV=production. (E: 897a6b5c4d3e2f10987654321fedcba0)');
304
+ throw new Error('EMAIL_MODE=mock is prohibited when NODE_ENV=production. (E: genuuid)');
305
305
  }
306
306
  return new EmailSenderMock();
307
307
  } else {
308
- throw new Error(`Unsupported EMAIL_MODE '${mode}'. Must be 'aws' or 'mock'. (E: 987a6b5c4d3e2f10987654321fedcba1)`);
308
+ throw new Error(`Unsupported EMAIL_MODE '${mode}'. Must be 'aws' or 'mock'. (E: genuuid)`);
309
309
  }
310
310
  }
311
311
 
@@ -21,7 +21,7 @@ export async function deriveCustodianAuthCode({
21
21
  const lc = `[${deriveCustodianAuthCode.name}]`;
22
22
  try {
23
23
  if (!serverSecret) {
24
- throw new Error('serverSecret required for custodian auth code derivation (E: a1b2c3d4e5f67890123456789abcdef0)');
24
+ throw new Error('serverSecret required for custodian auth code derivation (E: genuuid)');
25
25
  }
26
26
 
27
27
  const salt = await hash({
@@ -17,7 +17,7 @@ import {
17
17
  SsoProviderClientConfig
18
18
  } from './sso-types.mjs';
19
19
 
20
- const logalot = GLOBAL_LOG_A_LOT || true;
20
+ const logalot = GLOBAL_LOG_A_LOT;
21
21
 
22
22
  interface JwkKey {
23
23
  kty: string;
@@ -439,18 +439,18 @@ export class SsoCustodianService {
439
439
  });
440
440
 
441
441
  if (!targetKeystone) {
442
- throw new Error(`Keystone not found for address: ${keystoneAddr} (E: 8a9c2b1d3e5f6a7b8c9d0e1f2a3b4c5d)`);
442
+ throw new Error(`Keystone not found for address: ${keystoneAddr} (E: genuuid)`);
443
443
  }
444
444
 
445
445
  // 2. Locate native manage pool
446
446
  const userManagePool = targetKeystone.data?.challengePools.find(p => p.id === POOL_ID_MANAGE);
447
447
  if (!userManagePool) {
448
- throw new Error(`Keystone manage pool not found. Custodian manage pool must match the user manage pool's security config. (E: 7c4e5f6a7b8c9d0e1f2a3b4c5e6f7a8b)`);
448
+ throw new Error(`Keystone manage pool not found. Custodian manage pool must match the user manage pool's security config. (E: genuuid)`);
449
449
  }
450
450
 
451
451
  // 3. Dynamic poolId based on providerId with regex validation
452
452
  if (!providerId || !KEYSTONE_POOL_ID_REGEXP.test(providerId)) {
453
- throw new Error(`Invalid providerId: "${providerId}". Must match ${KEYSTONE_POOL_ID_REGEXP} (E: 3a2c4e5f6a7b8c9d0e1f2a3b4c5e6f)`);
453
+ throw new Error(`Invalid providerId: "${providerId}". Must match ${KEYSTONE_POOL_ID_REGEXP} (E: genuuid)`);
454
454
  }
455
455
  const poolId = `custodian-manage-${providerId}`;
456
456
 
@@ -52,7 +52,7 @@ export class EmailInboundHandler extends ServeGibHandlerBase {
52
52
 
53
53
  const inboundEmail = await this.receiver.parseInboundPayload(payload);
54
54
 
55
- console.log(`${lc} Successfully processed inbound email msgId: ${inboundEmail.messageId}, folder: ${inboundEmail.folder} (I: 890123456789abcdef8a9b0c1d2e3f4a)`);
55
+ console.log(`${lc} Successfully processed inbound email msgId: ${inboundEmail.messageId}, folder: ${inboundEmail.folder} (I: genuuid)`);
56
56
 
57
57
  return this.ok({
58
58
  success: true,
@@ -60,7 +60,7 @@ export class EmailInboundHandler extends ServeGibHandlerBase {
60
60
  });
61
61
  } catch (error) {
62
62
  const emsg = extractErrorMsg(error);
63
- console.error(`${lc} Inbound email handling failed: ${emsg} (E: 90123456789abcdef9a0b1c2d3e4f5a6)`);
63
+ console.error(`${lc} Inbound email handling failed: ${emsg} (E: genuuid)`);
64
64
  return this.error(500, `Inbound email error: ${emsg}`);
65
65
  }
66
66
  }
@@ -52,15 +52,15 @@ export class EmailOutboundHandler extends ServeGibHandlerBase {
52
52
  const sendResult = await this.sender.sendEmail(emailData);
53
53
 
54
54
  if (sendResult.success) {
55
- console.log(`${lc} Successfully dispatched outbound email msgId: ${sendResult.messageId} (I: 0123456789abcdef0a1b2c3d4e5f6a7b)`);
55
+ console.log(`${lc} Successfully dispatched outbound email msgId: ${sendResult.messageId} (I: genuuid)`);
56
56
  return this.ok(sendResult, sendResult.statusCode || 200);
57
57
  } else {
58
- console.error(`${lc} Failed to send email: ${sendResult.error} (E: 123456789abcdef1a2b3c4d5e6f7a8b9)`);
58
+ console.error(`${lc} Failed to send email: ${sendResult.error} (E: genuuid)`);
59
59
  return this.error(sendResult.statusCode || 500, sendResult.error || 'Failed to send email');
60
60
  }
61
61
  } catch (error) {
62
62
  const emsg = extractErrorMsg(error);
63
- console.error(`${lc} Outbound email error: ${emsg} (E: 23456789abcdef2a3b4c5d6e7f8a9b0c)`);
63
+ console.error(`${lc} Outbound email error: ${emsg} (E: genuuid)`);
64
64
  return this.error(500, `Outbound email error: ${emsg}`);
65
65
  }
66
66
  }
@@ -20,7 +20,7 @@ import { createDefaultEmailSender, generateVerificationCode, getPendingStagingDi
20
20
  import { validateEmail } from '../../../../email/email-helpers.mjs';
21
21
  import { normalizeEmail } from '../../../identity-index/identity-index-helpers.mjs';
22
22
 
23
- const logalot = GLOBAL_LOG_A_LOT || true;
23
+ const logalot = GLOBAL_LOG_A_LOT;
24
24
 
25
25
  export interface EmailMagicLinkHandlerOptions {
26
26
  sender?: EmailSender;
@@ -24,7 +24,7 @@ import { RequestContext, ResponseResult, ServeGibHttpMethod } from '../../../typ
24
24
  import { ServeGibHandlerBase } from '../../handler-base.mjs';
25
25
  import { GLOBAL_LOG_A_LOT } from '../../../constants.mjs';
26
26
 
27
- const logalot = GLOBAL_LOG_A_LOT || true;
27
+ const logalot = GLOBAL_LOG_A_LOT;
28
28
 
29
29
  export interface EmailVerifyCodeRequestBody {
30
30
  email: string;
@@ -33,7 +33,7 @@ await respecfully(sir, '6-Digit Verification Code & Server Quarantine Policy', a
33
33
  }
34
34
  mkdirSync(testDataDir, { recursive: true });
35
35
 
36
- await ifWeMight(sir, 'generate, verify, and enforce expiration & single-use rules on magic link tokens', async () => {
36
+ await ifWe(sir, 'generate, verify, and enforce expiration & single-use rules on magic link tokens', async () => {
37
37
  clearConsumedNonces();
38
38
  const email = 'alice@example.com';
39
39
  const primaryTjpAddr = 'keystone^ABC123DEF456_TJP';
@@ -69,7 +69,7 @@ await respecfully(sir, '6-Digit Verification Code & Server Quarantine Policy', a
69
69
  }
70
70
  });
71
71
 
72
- await ifWeMight(sir, 'create pending staging quarantine folder and AOT metadata files', async () => {
72
+ await ifWe(sir, 'create pending staging quarantine folder and AOT metadata files', async () => {
73
73
  clearConsumedNonces();
74
74
  const primaryTjpAddr = 'keystone^STAGING123_TJP';
75
75
  const mockKeystone = {
@@ -102,7 +102,7 @@ await respecfully(sir, '6-Digit Verification Code & Server Quarantine Policy', a
102
102
  iReckon(sir, meta1.verified).asTo('meta1 initial verified status').isGonnaBeFalse();
103
103
  });
104
104
 
105
- await ifWeMight(sir, 'handle 6-digit OTP code verification and promote identity upon verification', async () => {
105
+ await ifWe(sir, 'handle 6-digit OTP code verification and promote identity upon verification', async () => {
106
106
  clearConsumedNonces();
107
107
  const primaryTjpAddr = 'keystone^MULTIEMAIL_TJP';
108
108
  const email = 'multi1@example.com';
@@ -162,7 +162,7 @@ await respecfully(sir, '6-Digit Verification Code & Server Quarantine Policy', a
162
162
  iReckon(sir, record?.primaryTjpAddr).asTo('record primaryTjpAddr').isGonnaBe(primaryTjpAddr);
163
163
  });
164
164
 
165
- await ifWeMight(sir, 'execute atomic GC lockfile cleanup on expired staging directories', async () => {
165
+ await ifWe(sir, 'execute atomic GC lockfile cleanup on expired staging directories', async () => {
166
166
  clearConsumedNonces();
167
167
  const expiredTjpAddr = 'keystone^EXPIRED_TJP';
168
168
  const mockKeystone = { ib: expiredTjpAddr, data: { tjpAddr: expiredTjpAddr } };
@@ -34,7 +34,7 @@ import { getSsoCustodianService } from '../../../../identity/sso/sso-custodian-s
34
34
  import { SsoProviderId } from '../../../../identity/sso/sso-types.mjs';
35
35
  import { getPendingStagingDir, getPendingTjpHash, verifyPendingCode } from '../../../../email/verify/email-verify-helpers.mjs';
36
36
 
37
- const logalot = GLOBAL_LOG_A_LOT || true;
37
+ const logalot = GLOBAL_LOG_A_LOT;
38
38
 
39
39
  export interface CustodianAddMasterPasswordRequestBody {
40
40
  code: string;
@@ -67,35 +67,35 @@ export class KeystoneCustodianAddMasterPasswordHandler extends ServeGibHandlerBa
67
67
  ): Promise<ResponseResult | undefined> {
68
68
  const lc = `${this.lc}[${this.handleRouteImpl.name}]`;
69
69
  try {
70
- if (logalot) { console.log(`${lc} starting... (I: 8a1b2c3d4e5f67890a1b2c3d4e5f6790)`); }
70
+ if (logalot) { console.log(`${lc} starting... (I: genuuid)`); }
71
71
 
72
72
  if (reqCtx.method !== 'POST') {
73
73
  return this.error(405, 'Method Not Allowed');
74
74
  }
75
75
 
76
76
  if (!reqCtx.body) {
77
- return this.error(400, 'Request body is empty (E: 8a1b2c3d4e5f67890a1b2c3d4e5f6791)');
77
+ return this.error(400, 'Request body is empty (E: genuuid)');
78
78
  }
79
79
 
80
80
  let body: CustodianAddMasterPasswordRequestBody;
81
81
  try {
82
82
  body = JSON.parse(reqCtx.body);
83
83
  } catch {
84
- return this.error(400, 'Request body must be valid JSON (E: 8a1b2c3d4e5f67890a1b2c3d4e5f6792)');
84
+ return this.error(400, 'Request body must be valid JSON (E: genuuid)');
85
85
  }
86
86
 
87
87
  const { primaryTjpAddr, newManagePool, providerId, code, redirectUri, email } = body;
88
88
 
89
89
  if (!primaryTjpAddr) {
90
- return this.error(400, 'primaryTjpAddr is required (E: 8a1b2c3d4e5f67890a1b2c3d4e5f6793)');
90
+ return this.error(400, 'primaryTjpAddr is required (E: genuuid)');
91
91
  }
92
92
 
93
93
  if (!newManagePool || typeof newManagePool !== 'object' || newManagePool.id !== POOL_ID_MANAGE) {
94
- return this.error(400, 'newManagePool is invalid. Must be an object with id "manage" (E: 8a1b2c3d4e5f67890a1b2c3d4e5f6794)');
94
+ return this.error(400, 'newManagePool is invalid. Must be an object with id "manage" (E: genuuid)');
95
95
  }
96
96
 
97
97
  if (!newManagePool.challenges || Object.keys(newManagePool.challenges).length === 0) {
98
- return this.error(400, 'newManagePool must contain pre-generated public challenges (E: 8a1b2c3d4e5f67890a1b2c3d4e5f6795)');
98
+ return this.error(400, 'newManagePool must contain pre-generated public challenges (E: genuuid)');
99
99
  }
100
100
 
101
101
  // 1. Authenticate user credentials via OAuth code or Email OTP
@@ -106,12 +106,12 @@ export class KeystoneCustodianAddMasterPasswordHandler extends ServeGibHandlerBa
106
106
  const service = getSsoCustodianService();
107
107
  const userInfo = await service.getOAuthUserInfo(providerId, code, redirectUri);
108
108
  if (!userInfo || !userInfo.email) {
109
- return this.error(401, `Failed to authenticate with SSO provider ${providerId} (E: 8a1b2c3d4e5f67890a1b2c3d4e5f6796)`);
109
+ return this.error(401, `Failed to authenticate with SSO provider ${providerId} (E: genuuid)`);
110
110
  }
111
111
  verifiedEmail = normalizeEmail(userInfo.email);
112
112
  } else if (email && code) {
113
113
  if (!validateEmail(email)) {
114
- return this.error(400, 'Invalid email address format (E: 8a1b2c3d4e5f67890a1b2c3d4e5f6797)');
114
+ return this.error(400, 'Invalid email address format (E: genuuid)');
115
115
  }
116
116
  verifiedEmail = normalizeEmail(email);
117
117
 
@@ -123,7 +123,7 @@ export class KeystoneCustodianAddMasterPasswordHandler extends ServeGibHandlerBa
123
123
  }
124
124
 
125
125
  if (!pendingInfo || pendingInfo.isExpired) {
126
- return this.error(400, 'Verification record missing or expired. Please request a new verification code. (E: 8a1b2c3d4e5f67890a1b2c3d4e5f6798)');
126
+ return this.error(400, 'Verification record missing or expired. Please request a new verification code. (E: genuuid)');
127
127
  }
128
128
 
129
129
  const codeVerifyResult = await verifyPendingCode({
@@ -132,17 +132,17 @@ export class KeystoneCustodianAddMasterPasswordHandler extends ServeGibHandlerBa
132
132
  });
133
133
 
134
134
  if (!codeVerifyResult.valid) {
135
- return this.error(401, codeVerifyResult.error || 'Invalid verification code (E: 8a1b2c3d4e5f67890a1b2c3d4e5f6799)');
135
+ return this.error(401, codeVerifyResult.error || 'Invalid verification code (E: genuuid)');
136
136
  }
137
137
  } else {
138
- return this.error(400, 'Authentication credentials required (providerId+code+redirectUri or email+code) (E: 8a1b2c3d4e5f67890a1b2c3d4e5f679a)');
138
+ return this.error(400, 'Authentication credentials required (providerId+code+redirectUri or email+code) (E: genuuid)');
139
139
  }
140
140
 
141
141
  // 2. Lookup primary identity and confirm email matches
142
142
  const indexService = getIdentityIndexService();
143
143
  const identityRecord = await indexService.lookupIdentityByEmail({ email: verifiedEmail });
144
144
  if (!identityRecord || identityRecord.primaryTjpAddr !== primaryTjpAddr) {
145
- return this.error(403, `Authenticated email ${verifiedEmail} does not match primary identity ${primaryTjpAddr} (E: 8a1b2c3d4e5f67890a1b2c3d4e5f679b)`);
145
+ return this.error(403, `Authenticated email ${verifiedEmail} does not match primary identity ${primaryTjpAddr} (E: genuuid)`);
146
146
  }
147
147
 
148
148
  // 3. Bootstrap domain metaspace and load latest keystone
@@ -167,12 +167,12 @@ export class KeystoneCustodianAddMasterPasswordHandler extends ServeGibHandlerBa
167
167
  const prevPools = latestKeystone.data.challengePools || [];
168
168
  const existingManagePool = prevPools.find(p => p.id === POOL_ID_MANAGE);
169
169
  if (!existingManagePool) {
170
- return this.error(400, 'Primary keystone missing active "manage" pool (E: 8a1b2c3d4e5f67890a1b2c3d4e5f679c)');
170
+ return this.error(400, 'Primary keystone missing active "manage" pool (E: genuuid)');
171
171
  }
172
172
 
173
173
  // Validate new pool config matches existing manage pool config structure
174
174
  if (existingManagePool.config?.type && newManagePool.config?.type !== existingManagePool.config.type) {
175
- return this.error(400, `newManagePool type "${newManagePool.config?.type}" does not match required type "${existingManagePool.config.type}" (E: 8a1b2c3d4e5f67890a1b2c3d4e5f679d)`);
175
+ return this.error(400, `newManagePool type "${newManagePool.config?.type}" does not match required type "${existingManagePool.config.type}" (E: genuuid)`);
176
176
  }
177
177
 
178
178
  // 5. Build next pool set:
@@ -29,7 +29,7 @@ import { generateCustodianRequirements } from '../../../../identity/sso/custodia
29
29
  import { CustodianRequirements } from '../../../../identity/sso/sso-types.mjs';
30
30
  import { getPendingStagingDir, getPendingTjpHash, verifyPendingCode } from '../../../../email/verify/email-verify-helpers.mjs';
31
31
 
32
- const logalot = GLOBAL_LOG_A_LOT || true;
32
+ const logalot = GLOBAL_LOG_A_LOT;
33
33
 
34
34
  export interface CustodianGenesisRequestBody {
35
35
  email: string;
@@ -141,7 +141,7 @@ export class KeystoneCustodianGenesisHandler extends ServeGibHandlerBase<undefin
141
141
  const defaultUsername = username || normEmail.split('@')[0];
142
142
  const primaryProfileName = process.env.KEYSTONE_PROFILE_CUSTODIAN_PRIMARY;
143
143
  if (!primaryProfileName || !primaryProfileName.trim()) {
144
- throw new Error('KEYSTONE_PROFILE_CUSTODIAN_PRIMARY environment variable is missing. Expected valid profile name like "primary-profile.dev" or "primary-profile.prod". (E: 1a2b3c4d5e6f7890123456789abcdef1)');
144
+ throw new Error('KEYSTONE_PROFILE_CUSTODIAN_PRIMARY environment variable is missing. Expected valid profile name like "primary-profile.dev" or "primary-profile.prod". (E: genuuid)');
145
145
  }
146
146
 
147
147
  const primaryBuilder = KeystoneProfileBuilder.buildKeystone(primaryProfileName.trim() as any)
@@ -29,7 +29,7 @@ import { loadSsoServerConfig } from '../../../../identity/sso/sso-config-helper.
29
29
  import { getAuthCustodianIndex, verifyCustodianRequirements } from '../../../../identity/sso/custodian-auth-helpers.mjs';
30
30
  import { CustodianRequirements } from '../../../../identity/sso/sso-types.mjs';
31
31
 
32
- const logalot = GLOBAL_LOG_A_LOT || true;
32
+ const logalot = GLOBAL_LOG_A_LOT;
33
33
 
34
34
  export interface CustodianRegisterDelegateRequestBody {
35
35
  delegateKeystone: any;
@@ -47,7 +47,7 @@ import { getDomainRootPath } from '../../../bootstrap-helper.mjs';
47
47
  import { bootstrapDomainMetaspace } from '../../../bootstrap-helper.mjs';
48
48
  import { savePendingStagingKeystone, dispatchVerificationCode } from '../../../../email/verify/email-verify-helpers.mjs';
49
49
 
50
- const logalot = GLOBAL_LOG_A_LOT || true;
50
+ const logalot = GLOBAL_LOG_A_LOT;
51
51
 
52
52
 
53
53
  /**
@@ -170,7 +170,7 @@ export class KeystoneGenesisHandler extends ServeGibHandlerBase<undefined, undef
170
170
  // ----------------------------------------------------------------
171
171
  const space = await metaspace.getLocalUserSpace({ lock: false });
172
172
  if (!space) {
173
- throw new Error(`(UNEXPECTED) Could not get local user space after bootstrapping domain for ${addr} (E: b1c2d3e4f5a6b7c8d9e0f1a2b3c4d526)`);
173
+ throw new Error(`(UNEXPECTED) Could not get local user space after bootstrapping domain for ${addr} (E: genuuid)`);
174
174
  }
175
175
 
176
176
  await metaspace.put({ ibGibs: [keystoneIbGib], space });
@@ -15,7 +15,7 @@ import { RequestContext, ResponseResult, ServeGibHttpMethod } from '../../../typ
15
15
  import { API_PATH_REGEXES } from '../../../path-constants.mjs';
16
16
  import { bootstrapDomainMetaspace } from '../../../bootstrap-helper.mjs';
17
17
 
18
- const logalot = GLOBAL_LOG_A_LOT || true;
18
+ const logalot = GLOBAL_LOG_A_LOT;
19
19
 
20
20
  /**
21
21
  * POST /api/keystone/lookup
@@ -14,7 +14,7 @@ import { ServeGibHandlerWithMetaspaceBase } from '../../handler-base.mjs';
14
14
  import { API_PATH_REGEXES } from '../../../path-constants.mjs';
15
15
  import { ParamsWithDomain, RequestContext, ResponseResult, ServeGibHttpMethod } from '../../../types.mjs';
16
16
 
17
- const logalot = GLOBAL_LOG_A_LOT || true;
17
+ const logalot = GLOBAL_LOG_A_LOT;
18
18
 
19
19
  interface LinkParams extends ParamsWithDomain {
20
20
  parentTjpAddr: string;
@@ -76,25 +76,25 @@ export class SsoLinkHandler extends ServeGibHandlerWithMetaspaceBase<LinkParams,
76
76
  protected async handleRouteImpl(reqCtx: RequestContext<LinkParams>): Promise<ResponseResult | undefined> {
77
77
  const lc = `${this.lc}[${this.handleRouteImpl.name}]`;
78
78
  try {
79
- if (logalot) { console.log(`${lc} starting... (I: 8a4c1f930e7b2d5a6c1e9f8a3b5c7d1e)`); }
79
+ if (logalot) { console.log(`${lc} starting... (I: genuuid)`); }
80
80
 
81
81
  if (!reqCtx.params) {
82
- return this.error(400, 'Invalid parameters: parentTjpAddr missing (E: c9f1a2b3d4e5f60718293a4b5c6d7e8f)');
82
+ return this.error(400, 'Invalid parameters: parentTjpAddr missing (E: genuuid)');
83
83
  }
84
84
  if (!reqCtx.metaspace) {
85
- return this.error(500, 'Metaspace not initialized (E: d0a1b2c3d4e5f6789a0b1c2d3e4f5a6b)');
85
+ return this.error(500, 'Metaspace not initialized (E: genuuid)');
86
86
  }
87
87
 
88
88
  let parsed: LinkBody;
89
89
  try {
90
90
  parsed = JSON.parse(reqCtx.body);
91
91
  } catch {
92
- return this.error(400, 'Request body must be valid JSON (E: e1b2c3d4e5f67890a1b2c3d4e5f67890)');
92
+ return this.error(400, 'Request body must be valid JSON (E: genuuid)');
93
93
  }
94
94
 
95
95
  let { code, providerId, parentTjpAddr, userNonce, redirectUri } = parsed;
96
96
  if (!code || !providerId || !parentTjpAddr || !userNonce || !redirectUri) {
97
- return this.error(400, 'Body missing required parameters (code, providerId, parentTjpAddr, userNonce, redirectUri) (E: f2c3d4e5f6789012a3b4c5d6e7f89012)');
97
+ return this.error(400, 'Body missing required parameters (code, providerId, parentTjpAddr, userNonce, redirectUri) (E: genuuid)');
98
98
  }
99
99
 
100
100
  if (logalot) { console.log(`${lc} LinkBody parsed (I: 7525b8bd29c8504e989e918825d4e826)`); }
@@ -63,21 +63,21 @@ export class SsoLoginHandler extends ServeGibHandlerBase<undefined, undefined> {
63
63
  ): Promise<ResponseResult | undefined> {
64
64
  const lc = `${this.lc}[${this.handleRouteImpl.name}]`;
65
65
  try {
66
- if (logalot) { console.log(`${lc} starting... (I: 9b5d2a3c4e5f67890a1b2c3d4e5f6789)`); }
66
+ if (logalot) { console.log(`${lc} starting... (I: genuuid)`); }
67
67
 
68
68
  if (reqCtx.method !== 'POST') {
69
69
  return this.error(405, 'Method Not Allowed');
70
70
  }
71
71
 
72
72
  if (!reqCtx.body) {
73
- return this.error(400, 'Request body is empty (E: 0a1b2c3d4e5f67890a1b2c3d4e5f6789)');
73
+ return this.error(400, 'Request body is empty (E: genuuid)');
74
74
  }
75
75
 
76
76
  let parsed: SsoLoginBody;
77
77
  try {
78
78
  parsed = JSON.parse(reqCtx.body);
79
79
  } catch {
80
- return this.error(400, 'Request body must be valid JSON (E: 1a1b2c3d4e5f67890a1b2c3d4e5f6789)');
80
+ return this.error(400, 'Request body must be valid JSON (E: genuuid)');
81
81
  }
82
82
 
83
83
  const { code, providerId, redirectUri } = parsed;
@@ -5,7 +5,7 @@ import { KEYSTONE_EMAIL_REGEXP } from '@ibgib/core-gib/dist/keystone/keystone-co
5
5
  import { GLOBAL_LOG_A_LOT } from '../server-constants.mjs';
6
6
  import { DEFAULT_EMAIL_HASHES_SUBDIR, DEFAULT_IDENTITY_INDEX_SALT } from './identity-index-constants.mjs';
7
7
 
8
- const logalot = GLOBAL_LOG_A_LOT || true;
8
+ const logalot = GLOBAL_LOG_A_LOT;
9
9
 
10
10
  /**
11
11
  * Validates an email address against length constraints and KEYSTONE_EMAIL_REGEXP.
@@ -9,7 +9,7 @@ import { DEFAULT_IDENTITY_INDEX_SALT, DEFAULT_IDENTITY_INDEX_DIR_NAME } from './
9
9
  import { getIdentityEmailHash, getShardedIndexPath } from './identity-index-helpers.mjs';
10
10
  import { IdentityIndexRecord, IdentityIndexServiceOptions, RegisterEmailIndexResult } from './identity-index-types.mjs';
11
11
 
12
- const logalot = GLOBAL_LOG_A_LOT || true;
12
+ const logalot = GLOBAL_LOG_A_LOT;
13
13
 
14
14
  /**
15
15
  * Service managing atomic, sharded identity index files for backwards email -> primary identity tjpAddr lookups.
@@ -0,0 +1,104 @@
1
+ /**
2
+ * @module workspace-space-helper
3
+ *
4
+ * Helper for managing NodeWorkspaceProjectionSpace_V1 in metaspace.
5
+ */
6
+
7
+ import { clone, extractErrorMsg, getUUID } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
8
+ import { Metaspace_Nodespace } from '../witness/space/metaspace/metaspace-nodespace/metaspace-nodespace.mjs';
9
+ import { NodeWorkspaceProjectionSpace_V1 } from '../witness/space/node-workspace-projection-space/node-workspace-projection-space-v1.mjs';
10
+ import { IbGibSpaceAny } from '@ibgib/core-gib/dist/witness/space/space-base-v1.mjs';
11
+ import { GLOBAL_LOG_A_LOT } from '@ibgib/core-gib/dist/core-constants.mjs';
12
+
13
+ const lcFile = `[workspace-space-helper]`;
14
+ const logalot = GLOBAL_LOG_A_LOT;
15
+
16
+ export interface GetOrCreateWorkspaceProjectionSpaceOpts {
17
+ metaspace: Metaspace_Nodespace;
18
+ workspaceRoot: string;
19
+ vcsFolderName?: string;
20
+ backingSpace: IbGibSpaceAny;
21
+ branchAddr?: string;
22
+ name?: string;
23
+ }
24
+
25
+ export interface GetOrCreateWorkspaceProjectionSpaceResult {
26
+ space: NodeWorkspaceProjectionSpace_V1;
27
+ spaceId: string;
28
+ spaceName: string;
29
+ }
30
+
31
+ /**
32
+ * Gets an existing projection space for a workspace root or instantiates and returns a NodeWorkspaceProjectionSpace_V1.
33
+ */
34
+ export async function getOrCreateWorkspaceProjectionSpace({
35
+ metaspace,
36
+ workspaceRoot,
37
+ vcsFolderName = '.vcsgib',
38
+ backingSpace,
39
+ branchAddr,
40
+ name,
41
+ }: GetOrCreateWorkspaceProjectionSpaceOpts): Promise<GetOrCreateWorkspaceProjectionSpaceResult> {
42
+ const lc = `${lcFile}[${getOrCreateWorkspaceProjectionSpace.name}]`;
43
+ try {
44
+ if (logalot) {
45
+ console.log(`${lc} starting... (I: genuuid)`);
46
+ }
47
+
48
+ if (!metaspace || !workspaceRoot || !backingSpace) {
49
+ throw new Error(`metaspace, workspaceRoot, and backingSpace are required (E: genuuid)`);
50
+ }
51
+
52
+ const spaceName = name || `ws_${workspaceRoot.replace(/[^a-zA-Z0-9_]/g, '_')}`;
53
+
54
+ const localSpaces = (await metaspace.getLocalUserSpaces({ lock: false })) || [];
55
+ const existingSpace = localSpaces.find(s =>
56
+ (s.data?.name === spaceName || s.ib === spaceName) ||
57
+ (s.data?.classname?.includes('WorkspaceProjectionSpace') && s.data?.workspaceRoot === workspaceRoot)
58
+ );
59
+
60
+ if (existingSpace) {
61
+ const spaceId = existingSpace.data?.uuid || existingSpace.data?.spaceId || spaceName;
62
+ if (logalot) {
63
+ console.log(`${lc} Found existing workspace projection space ${spaceName} (spaceId: ${spaceId})`);
64
+ }
65
+ return {
66
+ space: existingSpace as NodeWorkspaceProjectionSpace_V1,
67
+ spaceId,
68
+ spaceName,
69
+ };
70
+ }
71
+
72
+ const spaceUuid = await getUUID();
73
+ const space = new NodeWorkspaceProjectionSpace_V1({
74
+ initialData: {
75
+ workspaceRoot,
76
+ vcsFolderName,
77
+ classname: 'NodeWorkspaceProjectionSpace_V1',
78
+ name: spaceName,
79
+ uuid: spaceUuid,
80
+ version: '1',
81
+ branchAddr,
82
+ },
83
+ backingSpace,
84
+ });
85
+ await space.initialized;
86
+
87
+ if (logalot) {
88
+ console.log(`${lc} Created new workspace projection space ${spaceName} (spaceId: ${spaceUuid})`);
89
+ }
90
+
91
+ return {
92
+ space,
93
+ spaceId: spaceUuid,
94
+ spaceName,
95
+ };
96
+ } catch (error) {
97
+ console.error(`${lc} ${extractErrorMsg(error)} (E: genuuid)`);
98
+ throw error;
99
+ } finally {
100
+ if (logalot) {
101
+ console.log(`${lc} complete.`);
102
+ }
103
+ }
104
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @module node-workspace-projection-space-constants
3
+ *
4
+ * Constants for Node.js workspace projection spaces.
5
+ */
6
+
7
+ export const DEFAULT_NODE_WORKSPACE_PROJECTION_SPACE_DESCRIPTION =
8
+ 'Node.js space witness for projecting and observing workspace hierarchies on physical disk.';
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @module node-workspace-projection-space-types
3
+ *
4
+ * Types for Node.js workspace projection spaces.
5
+ */
6
+
7
+ import {
8
+ WorkspaceProjectionSpaceData_V1,
9
+ WorkspaceProjectionSpaceRel8ns_V1
10
+ } from '@ibgib/core-gib/dist/witness/space/workspace-projection-space/workspace-projection-space-types.mjs';
11
+ import {
12
+ DEFAULT_LOCAL_SPACE_POLLING_INTERVAL_MS,
13
+ IBGIB_SPACE_NAME_DEFAULT,
14
+ ZERO_SPACE_ID
15
+ } from '@ibgib/core-gib/dist/witness/space/space-constants.mjs';
16
+ import {
17
+ DEFAULT_NODE_WORKSPACE_PROJECTION_SPACE_DESCRIPTION
18
+ } from './node-workspace-projection-space-constants.mjs';
19
+
20
+ /**
21
+ * Data payload for NodeWorkspaceProjectionSpace_V1.
22
+ */
23
+ export interface NodeWorkspaceProjectionSpaceData_V1 extends WorkspaceProjectionSpaceData_V1 {
24
+ }
25
+
26
+ export const DEFAULT_NODE_WORKSPACE_PROJECTION_SPACE_DATA_V1: NodeWorkspaceProjectionSpaceData_V1 = {
27
+ version: '1',
28
+ uuid: ZERO_SPACE_ID,
29
+ name: IBGIB_SPACE_NAME_DEFAULT,
30
+ classname: 'NodeWorkspaceProjectionSpace_V1',
31
+ workspaceRoot: '',
32
+ vcsFolderName: '.vcsgib',
33
+ persistOptsAndResultIbGibs: false,
34
+ validateIbGibAddrsMatchIbGibs: false,
35
+ longPollingIntervalMs: DEFAULT_LOCAL_SPACE_POLLING_INTERVAL_MS,
36
+ allowPrimitiveArgs: false,
37
+ catchAllErrors: true,
38
+ description: DEFAULT_NODE_WORKSPACE_PROJECTION_SPACE_DESCRIPTION,
39
+ trace: false,
40
+ };
41
+
42
+ export interface NodeWorkspaceProjectionSpaceRel8ns_V1 extends WorkspaceProjectionSpaceRel8ns_V1 {
43
+ }