@hed-hog/core 0.0.385 → 0.0.387

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 (146) hide show
  1. package/dist/app-command/app-command.registry.d.ts +2 -0
  2. package/dist/app-command/app-command.registry.d.ts.map +1 -1
  3. package/dist/app-command/app-command.registry.js.map +1 -1
  4. package/dist/auth/auth.controller.d.ts +24 -1
  5. package/dist/auth/auth.controller.d.ts.map +1 -1
  6. package/dist/auth/auth.controller.js +27 -0
  7. package/dist/auth/auth.controller.js.map +1 -1
  8. package/dist/auth/auth.service.d.ts +52 -1
  9. package/dist/auth/auth.service.d.ts.map +1 -1
  10. package/dist/auth/auth.service.js +108 -0
  11. package/dist/auth/auth.service.js.map +1 -1
  12. package/dist/auth/dto/complete-account.dto.d.ts +9 -0
  13. package/dist/auth/dto/complete-account.dto.d.ts.map +1 -0
  14. package/dist/auth/dto/complete-account.dto.js +43 -0
  15. package/dist/auth/dto/complete-account.dto.js.map +1 -0
  16. package/dist/authorize/authorize.controller.d.ts +45 -0
  17. package/dist/authorize/authorize.controller.d.ts.map +1 -0
  18. package/dist/authorize/authorize.controller.js +120 -0
  19. package/dist/authorize/authorize.controller.js.map +1 -0
  20. package/dist/authorize/authorize.module.d.ts +8 -0
  21. package/dist/authorize/authorize.module.d.ts.map +1 -0
  22. package/dist/authorize/authorize.module.js +36 -0
  23. package/dist/authorize/authorize.module.js.map +1 -0
  24. package/dist/authorize/authorize.service.d.ts +79 -0
  25. package/dist/authorize/authorize.service.d.ts.map +1 -0
  26. package/dist/authorize/authorize.service.js +196 -0
  27. package/dist/authorize/authorize.service.js.map +1 -0
  28. package/dist/authorize/dto/authorize-info.dto.d.ts +8 -0
  29. package/dist/authorize/dto/authorize-info.dto.d.ts.map +1 -0
  30. package/dist/authorize/dto/authorize-info.dto.js +42 -0
  31. package/dist/authorize/dto/authorize-info.dto.js.map +1 -0
  32. package/dist/authorize/dto/consent.dto.d.ts +8 -0
  33. package/dist/authorize/dto/consent.dto.d.ts.map +1 -0
  34. package/dist/authorize/dto/consent.dto.js +42 -0
  35. package/dist/authorize/dto/consent.dto.js.map +1 -0
  36. package/dist/authorize/dto/token.dto.d.ts +8 -0
  37. package/dist/authorize/dto/token.dto.d.ts.map +1 -0
  38. package/dist/authorize/dto/token.dto.js +42 -0
  39. package/dist/authorize/dto/token.dto.js.map +1 -0
  40. package/dist/challenge/challenge.service.d.ts +7 -0
  41. package/dist/challenge/challenge.service.d.ts.map +1 -1
  42. package/dist/challenge/challenge.service.js +22 -0
  43. package/dist/challenge/challenge.service.js.map +1 -1
  44. package/dist/core.module.d.ts.map +1 -1
  45. package/dist/core.module.js +2 -0
  46. package/dist/core.module.js.map +1 -1
  47. package/dist/file/file.service.d.ts +7 -0
  48. package/dist/file/file.service.d.ts.map +1 -1
  49. package/dist/file/file.service.js +16 -0
  50. package/dist/file/file.service.js.map +1 -1
  51. package/dist/index.d.ts +1 -0
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +1 -0
  54. package/dist/index.js.map +1 -1
  55. package/dist/integration-profile/integration-profile.secrets.d.ts +6 -2
  56. package/dist/integration-profile/integration-profile.secrets.d.ts.map +1 -1
  57. package/dist/integration-profile/integration-profile.secrets.js +14 -3
  58. package/dist/integration-profile/integration-profile.secrets.js.map +1 -1
  59. package/dist/integration-profile/integration-profile.service.d.ts +7 -0
  60. package/dist/integration-profile/integration-profile.service.d.ts.map +1 -1
  61. package/dist/integration-profile/integration-profile.service.js +91 -4
  62. package/dist/integration-profile/integration-profile.service.js.map +1 -1
  63. package/dist/integration-profile/integration-profile.utils.d.ts +28 -0
  64. package/dist/integration-profile/integration-profile.utils.d.ts.map +1 -1
  65. package/dist/integration-profile/integration-profile.utils.js +40 -1
  66. package/dist/integration-profile/integration-profile.utils.js.map +1 -1
  67. package/dist/oauth/interfaces/OAuthProvider.d.ts +1 -1
  68. package/dist/oauth/interfaces/OAuthProvider.d.ts.map +1 -1
  69. package/dist/oauth/oauth.controller.d.ts +26 -0
  70. package/dist/oauth/oauth.controller.d.ts.map +1 -1
  71. package/dist/oauth/oauth.controller.js +94 -0
  72. package/dist/oauth/oauth.controller.js.map +1 -1
  73. package/dist/oauth/oauth.service.d.ts +39 -1
  74. package/dist/oauth/oauth.service.d.ts.map +1 -1
  75. package/dist/oauth/oauth.service.js +115 -7
  76. package/dist/oauth/oauth.service.js.map +1 -1
  77. package/dist/oauth/providers/microsoft-entra-id.provider.d.ts +5 -1
  78. package/dist/oauth/providers/microsoft-entra-id.provider.d.ts.map +1 -1
  79. package/dist/oauth/providers/microsoft-entra-id.provider.js +37 -6
  80. package/dist/oauth/providers/microsoft-entra-id.provider.js.map +1 -1
  81. package/dist/profile/profile.controller.d.ts +4 -3
  82. package/dist/profile/profile.controller.d.ts.map +1 -1
  83. package/dist/profile/profile.controller.js.map +1 -1
  84. package/dist/profile/profile.service.d.ts +5 -4
  85. package/dist/profile/profile.service.d.ts.map +1 -1
  86. package/dist/profile/profile.service.js.map +1 -1
  87. package/dist/webhook-integration/webhook-integration.controller.d.ts +5 -8
  88. package/dist/webhook-integration/webhook-integration.controller.d.ts.map +1 -1
  89. package/dist/webhook-integration/webhook-integration.controller.js +31 -8
  90. package/dist/webhook-integration/webhook-integration.controller.js.map +1 -1
  91. package/dist/webhook-integration/webhook-integration.module.d.ts.map +1 -1
  92. package/dist/webhook-integration/webhook-integration.module.js +5 -0
  93. package/dist/webhook-integration/webhook-integration.module.js.map +1 -1
  94. package/dist/webhook-integration/webhook-integration.service.d.ts +33 -1
  95. package/dist/webhook-integration/webhook-integration.service.d.ts.map +1 -1
  96. package/dist/webhook-integration/webhook-integration.service.js +116 -5
  97. package/dist/webhook-integration/webhook-integration.service.js.map +1 -1
  98. package/dist/webhook-integration/webhook-protocol.registry.d.ts +63 -0
  99. package/dist/webhook-integration/webhook-protocol.registry.d.ts.map +1 -0
  100. package/dist/webhook-integration/webhook-protocol.registry.js +51 -0
  101. package/dist/webhook-integration/webhook-protocol.registry.js.map +1 -0
  102. package/hedhog/data/integration_provider.yaml +8 -0
  103. package/hedhog/data/integration_type.yaml +6 -0
  104. package/hedhog/data/mail.yaml +39 -0
  105. package/hedhog/data/route.yaml +12 -0
  106. package/hedhog/data/setting_group.yaml +15 -1
  107. package/hedhog/frontend/app/account/components/regenerate-codes-dialog.tsx.ejs +11 -7
  108. package/hedhog/frontend/app/account/components/verify-before-add-dialog.tsx.ejs +9 -7
  109. package/hedhog/frontend/app/account/hooks/use-mfa-setup.ts.ejs +6 -2
  110. package/hedhog/frontend/app/dashboard/dashboard-home-tabs.tsx.ejs +130 -34
  111. package/hedhog/frontend/app/integration/profiles/page.tsx.ejs +16 -8
  112. package/hedhog/frontend/messages/en.json +55 -1
  113. package/hedhog/frontend/messages/pt.json +55 -1
  114. package/hedhog/table/webhook_integration.yaml +64 -43
  115. package/package.json +10 -5
  116. package/src/app-command/app-command.registry.ts +2 -0
  117. package/src/auth/auth.controller.ts +23 -1
  118. package/src/auth/auth.service.ts +135 -1
  119. package/src/auth/dto/complete-account.dto.ts +24 -0
  120. package/src/authorize/authorize.controller.ts +99 -0
  121. package/src/authorize/authorize.module.ts +23 -0
  122. package/src/authorize/authorize.service.spec.ts +307 -0
  123. package/src/authorize/authorize.service.ts +245 -0
  124. package/src/authorize/dto/authorize-info.dto.ts +23 -0
  125. package/src/authorize/dto/consent.dto.ts +23 -0
  126. package/src/authorize/dto/token.dto.ts +23 -0
  127. package/src/challenge/challenge.service.ts +28 -0
  128. package/src/core.module.ts +2 -0
  129. package/src/file/file.service.ts +19 -0
  130. package/src/index.ts +1 -0
  131. package/src/integration-profile/integration-profile.secrets.spec.ts +114 -0
  132. package/src/integration-profile/integration-profile.secrets.ts +14 -3
  133. package/src/integration-profile/integration-profile.service.ts +129 -3
  134. package/src/integration-profile/integration-profile.utils.spec.ts +75 -0
  135. package/src/integration-profile/integration-profile.utils.ts +79 -0
  136. package/src/oauth/interfaces/OAuthProvider.ts +5 -1
  137. package/src/oauth/oauth.controller.ts +89 -0
  138. package/src/oauth/oauth.service.ts +190 -8
  139. package/src/oauth/providers/microsoft-entra-id.provider.ts +45 -5
  140. package/src/profile/profile.controller.ts +6 -2
  141. package/src/profile/profile.service.ts +5 -3
  142. package/src/webhook-integration/webhook-integration.controller.ts +40 -2
  143. package/src/webhook-integration/webhook-integration.module.ts +5 -0
  144. package/src/webhook-integration/webhook-integration.service.ts +151 -2
  145. package/src/webhook-integration/webhook-protocol.registry.spec.ts +70 -0
  146. package/src/webhook-integration/webhook-protocol.registry.ts +93 -0
@@ -0,0 +1,70 @@
1
+ import { describe, expect, it, jest } from '@jest/globals';
2
+ import { WebhookProtocolRegistry } from './webhook-protocol.registry';
3
+
4
+ const makeAdapter = () =>
5
+ ({
6
+ verify: jest.fn(),
7
+ handle: jest.fn(),
8
+ }) as any;
9
+
10
+ describe('WebhookProtocolRegistry', () => {
11
+ it('devolve o adaptador registrado', () => {
12
+ const registry = new WebhookProtocolRegistry();
13
+ const adapter = makeAdapter();
14
+
15
+ registry.register('meta-whatsapp', adapter);
16
+
17
+ expect(registry.get('meta-whatsapp')).toBe(adapter);
18
+ expect(registry.has('meta-whatsapp')).toBe(true);
19
+ });
20
+
21
+ it('normaliza a chave (case e espaços)', () => {
22
+ const registry = new WebhookProtocolRegistry();
23
+ const adapter = makeAdapter();
24
+
25
+ registry.register(' Meta-WhatsApp ', adapter);
26
+
27
+ expect(registry.get('meta-whatsapp')).toBe(adapter);
28
+ expect(registry.get('META-WHATSAPP')).toBe(adapter);
29
+ });
30
+
31
+ it('devolve null para protocolo desconhecido, nulo ou vazio', () => {
32
+ const registry = new WebhookProtocolRegistry();
33
+
34
+ expect(registry.get('nao-existe')).toBeNull();
35
+ expect(registry.get(null)).toBeNull();
36
+ expect(registry.get(undefined)).toBeNull();
37
+ expect(registry.get('')).toBeNull();
38
+ expect(registry.has(null)).toBe(false);
39
+ });
40
+
41
+ it('recusa registrar com chave vazia', () => {
42
+ const registry = new WebhookProtocolRegistry();
43
+
44
+ expect(() => registry.register(' ', makeAdapter())).toThrow();
45
+ });
46
+
47
+ it('avisa ao sobrescrever um protocolo já registrado', () => {
48
+ const registry = new WebhookProtocolRegistry();
49
+ const warn = jest
50
+ .spyOn((registry as any).logger, 'warn')
51
+ .mockImplementation(() => undefined);
52
+ const first = makeAdapter();
53
+ const second = makeAdapter();
54
+
55
+ registry.register('dup', first);
56
+ registry.register('dup', second);
57
+
58
+ // Sobrescrever silenciosamente esconderia dois módulos brigando pelo protocolo.
59
+ expect(warn).toHaveBeenCalled();
60
+ expect(registry.get('dup')).toBe(second);
61
+ });
62
+
63
+ it('lista os protocolos registrados em ordem', () => {
64
+ const registry = new WebhookProtocolRegistry();
65
+ registry.register('zeta', makeAdapter());
66
+ registry.register('alpha', makeAdapter());
67
+
68
+ expect(registry.list()).toEqual(['alpha', 'zeta']);
69
+ });
70
+ });
@@ -0,0 +1,93 @@
1
+ import { Injectable, Logger } from '@nestjs/common';
2
+ import { Request } from 'express';
3
+
4
+ /**
5
+ * Resposta que um adaptador devolve ao controller público.
6
+ *
7
+ * `contentType` existe porque nem todo provedor aceita JSON: o handshake da Meta,
8
+ * por exemplo, compara o corpo com o challenge literalmente — um envelope JSON
9
+ * reprova a verificação.
10
+ */
11
+ export type WebhookProtocolResponse = {
12
+ status: number;
13
+ contentType?: string;
14
+ body: string | object;
15
+ };
16
+
17
+ export type WebhookProtocolRequest = {
18
+ /** O registro de webhook_integration que casou com o uuid da URL. */
19
+ integration: {
20
+ id: number;
21
+ slug: string;
22
+ integration_profile_id: number | null;
23
+ };
24
+ /** Body já parseado (POST) ou query params (GET). */
25
+ body: unknown;
26
+ query: Record<string, string>;
27
+ headers: Record<string, string | string[] | undefined>;
28
+ /**
29
+ * Bytes originais da requisição. Obrigatório para validar assinaturas HMAC:
30
+ * reserializar o JSON reordena chaves e invalida a assinatura.
31
+ */
32
+ rawBody?: Buffer;
33
+ remoteIp: string;
34
+ req: Request;
35
+ };
36
+
37
+ /**
38
+ * Adaptador de um protocolo de webhook de entrada.
39
+ *
40
+ * O framework de webhooks do core é um disparador de ações genérico, autenticado
41
+ * por token estático. Provedores como a Meta falam um protocolo próprio (handshake
42
+ * de verificação + assinatura HMAC) que não cabe nesse modelo.
43
+ *
44
+ * Em vez de espalhar `if (provider === 'meta')` pelo core, um módulo registra aqui
45
+ * um adaptador e passa a responder pela mesma URL pública (`/webhook/:uuid`). O core
46
+ * continua sem conhecer nenhum provedor específico.
47
+ */
48
+ export interface IWebhookProtocolAdapter {
49
+ /** GET na URL pública (tipicamente o handshake de verificação). */
50
+ verify(request: WebhookProtocolRequest): Promise<WebhookProtocolResponse>;
51
+ /** POST na URL pública (o evento em si). */
52
+ handle(request: WebhookProtocolRequest): Promise<WebhookProtocolResponse>;
53
+ }
54
+
55
+ /**
56
+ * Registro dos adaptadores de protocolo, no mesmo padrão do QueueHandlerRegistry
57
+ * e do FiscalProviderRegistry: o módulo dono do protocolo se registra no boot.
58
+ */
59
+ @Injectable()
60
+ export class WebhookProtocolRegistry {
61
+ private readonly logger = new Logger(WebhookProtocolRegistry.name);
62
+ private readonly adapters = new Map<string, IWebhookProtocolAdapter>();
63
+
64
+ register(protocol: string, adapter: IWebhookProtocolAdapter): void {
65
+ const key = normalizeProtocol(protocol);
66
+ if (!key) throw new Error('Webhook protocol key is required.');
67
+
68
+ if (this.adapters.has(key)) {
69
+ this.logger.warn(`Webhook protocol "${key}" was overwritten.`);
70
+ }
71
+
72
+ this.adapters.set(key, adapter);
73
+ this.logger.log(`Registered webhook protocol "${key}"`);
74
+ }
75
+
76
+ get(protocol: string | null | undefined): IWebhookProtocolAdapter | null {
77
+ const key = normalizeProtocol(protocol);
78
+ return key ? (this.adapters.get(key) ?? null) : null;
79
+ }
80
+
81
+ has(protocol: string | null | undefined): boolean {
82
+ return this.get(protocol) !== null;
83
+ }
84
+
85
+ /** Protocolos registrados (para a UI listar o que existe). */
86
+ list(): string[] {
87
+ return [...this.adapters.keys()].sort();
88
+ }
89
+ }
90
+
91
+ function normalizeProtocol(protocol: string | null | undefined): string {
92
+ return String(protocol ?? '').trim().toLowerCase();
93
+ }