@agenticmail/enterprise 0.5.3 → 0.5.5

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.
@@ -1,154 +0,0 @@
1
- // src/domain-lock/index.ts
2
- import { randomBytes } from "crypto";
3
- var REGISTRY_BASE_URL = process.env.AGENTICMAIL_REGISTRY_URL || "https://registry.agenticmail.com/v1";
4
- var DomainLock = class {
5
- registryUrl;
6
- constructor(opts) {
7
- this.registryUrl = (opts?.registryUrl || REGISTRY_BASE_URL).replace(/\/$/, "");
8
- }
9
- /**
10
- * Generate a 256-bit deployment key.
11
- * Returns the plaintext (hex) and its bcrypt hash.
12
- * The plaintext should be shown to the user ONCE and never stored.
13
- */
14
- async generateDeploymentKey() {
15
- const { default: bcrypt } = await import("bcryptjs");
16
- const plaintext = randomBytes(32).toString("hex");
17
- const hash = await bcrypt.hash(plaintext, 12);
18
- return { plaintext, hash };
19
- }
20
- /**
21
- * Register a domain with the central registry.
22
- * Called during setup wizard Step 5.
23
- *
24
- * @param domain - The domain to register (e.g. "agents.agenticmail.io")
25
- * @param keyHash - bcrypt hash of the deployment key
26
- * @param opts - Optional org name and contact email
27
- */
28
- async register(domain, keyHash, opts) {
29
- try {
30
- const res = await fetch(`${this.registryUrl}/domains/register`, {
31
- method: "POST",
32
- headers: { "Content-Type": "application/json" },
33
- body: JSON.stringify({
34
- domain: domain.toLowerCase().trim(),
35
- keyHash,
36
- orgName: opts?.orgName,
37
- contactEmail: opts?.contactEmail
38
- }),
39
- signal: AbortSignal.timeout(15e3)
40
- });
41
- const data = await res.json().catch(() => ({}));
42
- if (res.status === 409) {
43
- return {
44
- success: false,
45
- error: data.error || 'Domain is already registered and verified. Use "recover" if this is your domain.',
46
- statusCode: 409
47
- };
48
- }
49
- if (!res.ok) {
50
- return {
51
- success: false,
52
- error: data.error || `Registration failed (HTTP ${res.status})`,
53
- statusCode: res.status
54
- };
55
- }
56
- return {
57
- success: true,
58
- registrationId: data.registrationId,
59
- dnsChallenge: data.dnsChallenge
60
- };
61
- } catch (err) {
62
- if (err.name === "TimeoutError" || err.name === "AbortError") {
63
- return { success: false, error: "Registry server unreachable (timeout). You can retry later or continue without registration." };
64
- }
65
- return { success: false, error: `Registry connection failed: ${err.message}` };
66
- }
67
- }
68
- /**
69
- * Ask the registry to check DNS verification for a domain.
70
- * The registry resolves _agenticmail-verify.<domain> TXT record.
71
- */
72
- async checkVerification(domain) {
73
- try {
74
- const res = await fetch(`${this.registryUrl}/domains/verify`, {
75
- method: "POST",
76
- headers: { "Content-Type": "application/json" },
77
- body: JSON.stringify({ domain: domain.toLowerCase().trim() }),
78
- signal: AbortSignal.timeout(15e3)
79
- });
80
- const data = await res.json().catch(() => ({}));
81
- if (!res.ok) {
82
- return { success: false, error: data.error || `Verification check failed (HTTP ${res.status})` };
83
- }
84
- return {
85
- success: true,
86
- verified: data.verified === true,
87
- error: data.verified ? void 0 : data.error || "DNS record not found yet"
88
- };
89
- } catch (err) {
90
- if (err.name === "TimeoutError" || err.name === "AbortError") {
91
- return { success: false, error: "Registry server unreachable (timeout)" };
92
- }
93
- return { success: false, error: `Registry connection failed: ${err.message}` };
94
- }
95
- }
96
- /**
97
- * Recover a domain registration on a new machine.
98
- * Requires the original deployment key (plaintext).
99
- * The registry verifies via bcrypt.compare against stored hash.
100
- * On success, a new DNS challenge is issued (must re-verify DNS).
101
- */
102
- async recover(domain, deploymentKey) {
103
- try {
104
- const res = await fetch(`${this.registryUrl}/domains/recover`, {
105
- method: "POST",
106
- headers: { "Content-Type": "application/json" },
107
- body: JSON.stringify({
108
- domain: domain.toLowerCase().trim(),
109
- deploymentKey
110
- }),
111
- signal: AbortSignal.timeout(15e3)
112
- });
113
- const data = await res.json().catch(() => ({}));
114
- if (res.status === 403) {
115
- return { success: false, error: "Invalid deployment key. The key does not match the registered domain." };
116
- }
117
- if (res.status === 404) {
118
- return { success: false, error: "Domain is not registered. Use setup wizard to register first." };
119
- }
120
- if (!res.ok) {
121
- return { success: false, error: data.error || `Recovery failed (HTTP ${res.status})` };
122
- }
123
- return {
124
- success: true,
125
- dnsChallenge: data.dnsChallenge,
126
- registrationId: data.registrationId
127
- };
128
- } catch (err) {
129
- if (err.name === "TimeoutError" || err.name === "AbortError") {
130
- return { success: false, error: "Registry server unreachable (timeout)" };
131
- }
132
- return { success: false, error: `Registry connection failed: ${err.message}` };
133
- }
134
- }
135
- /**
136
- * Check domain status on the registry (public, read-only).
137
- */
138
- async getRemoteStatus(domain) {
139
- try {
140
- const res = await fetch(
141
- `${this.registryUrl}/domains/${encodeURIComponent(domain.toLowerCase().trim())}/status`,
142
- { signal: AbortSignal.timeout(1e4) }
143
- );
144
- if (!res.ok) return null;
145
- return await res.json();
146
- } catch {
147
- return null;
148
- }
149
- }
150
- };
151
-
152
- export {
153
- DomainLock
154
- };