@getbrevo/cli 0.0.1-alpha.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.
- package/CHANGELOG.md +13 -0
- package/LICENSE +21 -0
- package/README.md +182 -0
- package/dist/api/client.d.ts +23 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +186 -0
- package/dist/api/client.js.map +1 -0
- package/dist/bin/index.d.ts +3 -0
- package/dist/bin/index.d.ts.map +1 -0
- package/dist/bin/index.js +179 -0
- package/dist/bin/index.js.map +1 -0
- package/dist/commands/app/create.d.ts +7 -0
- package/dist/commands/app/create.d.ts.map +1 -0
- package/dist/commands/app/create.js +261 -0
- package/dist/commands/app/create.js.map +1 -0
- package/dist/commands/app/credentials.d.ts +6 -0
- package/dist/commands/app/credentials.d.ts.map +1 -0
- package/dist/commands/app/credentials.js +106 -0
- package/dist/commands/app/credentials.js.map +1 -0
- package/dist/commands/app/delete.d.ts +6 -0
- package/dist/commands/app/delete.d.ts.map +1 -0
- package/dist/commands/app/delete.js +146 -0
- package/dist/commands/app/delete.js.map +1 -0
- package/dist/commands/app/list.d.ts +4 -0
- package/dist/commands/app/list.d.ts.map +1 -0
- package/dist/commands/app/list.js +46 -0
- package/dist/commands/app/list.js.map +1 -0
- package/dist/commands/app/scaffold.d.ts +5 -0
- package/dist/commands/app/scaffold.d.ts.map +1 -0
- package/dist/commands/app/scaffold.js +199 -0
- package/dist/commands/app/scaffold.js.map +1 -0
- package/dist/commands/app/start.d.ts +5 -0
- package/dist/commands/app/start.d.ts.map +1 -0
- package/dist/commands/app/start.js +138 -0
- package/dist/commands/app/start.js.map +1 -0
- package/dist/commands/app/test.d.ts +6 -0
- package/dist/commands/app/test.d.ts.map +1 -0
- package/dist/commands/app/test.js +495 -0
- package/dist/commands/app/test.js.map +1 -0
- package/dist/commands/app/update.d.ts +2 -0
- package/dist/commands/app/update.d.ts.map +1 -0
- package/dist/commands/app/update.js +324 -0
- package/dist/commands/app/update.js.map +1 -0
- package/dist/commands/definitions.d.ts +4 -0
- package/dist/commands/definitions.d.ts.map +1 -0
- package/dist/commands/definitions.js +197 -0
- package/dist/commands/definitions.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +90 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +6 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +219 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +5 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +54 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/whoami.d.ts +4 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +74 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/container.d.ts +7 -0
- package/dist/container.d.ts.map +1 -0
- package/dist/container.js +28 -0
- package/dist/container.js.map +1 -0
- package/dist/lang/en.d.ts +110 -0
- package/dist/lang/en.d.ts.map +1 -0
- package/dist/lang/en.js +133 -0
- package/dist/lang/en.js.map +1 -0
- package/dist/lib/abort.d.ts +3 -0
- package/dist/lib/abort.d.ts.map +1 -0
- package/dist/lib/abort.js +30 -0
- package/dist/lib/abort.js.map +1 -0
- package/dist/lib/auth-guard.d.ts +3 -0
- package/dist/lib/auth-guard.d.ts.map +1 -0
- package/dist/lib/auth-guard.js +25 -0
- package/dist/lib/auth-guard.js.map +1 -0
- package/dist/lib/browser.d.ts +2 -0
- package/dist/lib/browser.d.ts.map +1 -0
- package/dist/lib/browser.js +16 -0
- package/dist/lib/browser.js.map +1 -0
- package/dist/lib/command-handler.d.ts +10 -0
- package/dist/lib/command-handler.d.ts.map +1 -0
- package/dist/lib/command-handler.js +16 -0
- package/dist/lib/command-handler.js.map +1 -0
- package/dist/lib/command-registry.d.ts +28 -0
- package/dist/lib/command-registry.d.ts.map +1 -0
- package/dist/lib/command-registry.js +54 -0
- package/dist/lib/command-registry.js.map +1 -0
- package/dist/lib/config.d.ts +76 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +314 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/constants.d.ts +35 -0
- package/dist/lib/constants.d.ts.map +1 -0
- package/dist/lib/constants.js +97 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/errors.d.ts +30 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +66 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/exit-codes.d.ts +9 -0
- package/dist/lib/exit-codes.d.ts.map +1 -0
- package/dist/lib/exit-codes.js +12 -0
- package/dist/lib/exit-codes.js.map +1 -0
- package/dist/lib/hidden-input.d.ts +2 -0
- package/dist/lib/hidden-input.d.ts.map +1 -0
- package/dist/lib/hidden-input.js +78 -0
- package/dist/lib/hidden-input.js.map +1 -0
- package/dist/lib/json-output.d.ts +6 -0
- package/dist/lib/json-output.d.ts.map +1 -0
- package/dist/lib/json-output.js +11 -0
- package/dist/lib/json-output.js.map +1 -0
- package/dist/lib/logger.d.ts +11 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +87 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/port.d.ts +12 -0
- package/dist/lib/port.d.ts.map +1 -0
- package/dist/lib/port.js +79 -0
- package/dist/lib/port.js.map +1 -0
- package/dist/lib/ui.d.ts +14 -0
- package/dist/lib/ui.d.ts.map +1 -0
- package/dist/lib/ui.js +75 -0
- package/dist/lib/ui.js.map +1 -0
- package/dist/lib/validators.d.ts +32 -0
- package/dist/lib/validators.d.ts.map +1 -0
- package/dist/lib/validators.js +96 -0
- package/dist/lib/validators.js.map +1 -0
- package/dist/services/account.d.ts +8 -0
- package/dist/services/account.d.ts.map +1 -0
- package/dist/services/account.js +15 -0
- package/dist/services/account.js.map +1 -0
- package/dist/services/app.d.ts +35 -0
- package/dist/services/app.d.ts.map +1 -0
- package/dist/services/app.js +117 -0
- package/dist/services/app.js.map +1 -0
- package/dist/services/browser-auth.d.ts +15 -0
- package/dist/services/browser-auth.d.ts.map +1 -0
- package/dist/services/browser-auth.js +187 -0
- package/dist/services/browser-auth.js.map +1 -0
- package/dist/services/normalize-app-id.d.ts +12 -0
- package/dist/services/normalize-app-id.d.ts.map +1 -0
- package/dist/services/normalize-app-id.js +38 -0
- package/dist/services/normalize-app-id.js.map +1 -0
- package/dist/services/oauth-refresh.d.ts +14 -0
- package/dist/services/oauth-refresh.d.ts.map +1 -0
- package/dist/services/oauth-refresh.js +70 -0
- package/dist/services/oauth-refresh.js.map +1 -0
- package/dist/templates/files/AGENTS.md.tmpl +41 -0
- package/dist/templates/files/CLAUDE.md.tmpl +50 -0
- package/dist/templates/files/README.md.tmpl +77 -0
- package/dist/templates/files/app-config.json.tmpl +23 -0
- package/dist/templates/files/gitignore.tmpl +9 -0
- package/dist/templates/files/src/oauth/.env.example.tmpl +13 -0
- package/dist/templates/files/src/oauth/.env.local.tmpl +10 -0
- package/dist/templates/files/src/oauth/handler.js.tmpl +203 -0
- package/dist/templates/files/src/oauth/package.json.tmpl +15 -0
- package/dist/templates/files/src/oauth/server.js.tmpl +226 -0
- package/dist/templates/files/src/oauth/token-store.js.tmpl +39 -0
- package/dist/templates/index.d.ts +36 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +105 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/types.d.ts +30 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +81 -0
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.testCommand = void 0;
|
|
37
|
+
const crypto = __importStar(require("crypto"));
|
|
38
|
+
const http = __importStar(require("http"));
|
|
39
|
+
const fs = __importStar(require("fs"));
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
const logger_1 = require("../../lib/logger");
|
|
42
|
+
const en_1 = require("../../lang/en");
|
|
43
|
+
const errors_1 = require("../../lib/errors");
|
|
44
|
+
const constants_1 = require("../../lib/constants");
|
|
45
|
+
const config_1 = require("../../lib/config");
|
|
46
|
+
const container_1 = require("../../container");
|
|
47
|
+
const command_handler_1 = require("../../lib/command-handler");
|
|
48
|
+
const ui_1 = require("../../lib/ui");
|
|
49
|
+
function parseEnvFile(filePath) {
|
|
50
|
+
const vars = {};
|
|
51
|
+
try {
|
|
52
|
+
if (!fs.existsSync(filePath))
|
|
53
|
+
return vars;
|
|
54
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
55
|
+
for (const line of content.split('\n')) {
|
|
56
|
+
const [key, ...rest] = line.split('=');
|
|
57
|
+
const value = rest.join('=').trim();
|
|
58
|
+
if (key?.trim() && value) {
|
|
59
|
+
vars[key.trim()] = value;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// ignore
|
|
65
|
+
}
|
|
66
|
+
return vars;
|
|
67
|
+
}
|
|
68
|
+
async function resolveCredentials(port, appIdOption) {
|
|
69
|
+
let clientId = process.env.CLIENT_ID;
|
|
70
|
+
let clientSecret = process.env.CLIENT_SECRET;
|
|
71
|
+
let redirectUri = process.env.REDIRECT_URI || `http://localhost:${port}/auth/callback`;
|
|
72
|
+
let scopes = ['all'];
|
|
73
|
+
// Try .env.local file in cwd
|
|
74
|
+
if (!clientId || !clientSecret) {
|
|
75
|
+
const envVars = parseEnvFile(path.resolve('.env.local'));
|
|
76
|
+
if (!clientId)
|
|
77
|
+
clientId = envVars.CLIENT_ID;
|
|
78
|
+
if (!clientSecret)
|
|
79
|
+
clientSecret = envVars.CLIENT_SECRET;
|
|
80
|
+
if (envVars.REDIRECT_URI)
|
|
81
|
+
redirectUri = envVars.REDIRECT_URI;
|
|
82
|
+
}
|
|
83
|
+
// Try --app-id flag or app-config.json
|
|
84
|
+
if (!clientId || !clientSecret) {
|
|
85
|
+
let appId = appIdOption;
|
|
86
|
+
if (!appId) {
|
|
87
|
+
const projectConfig = (0, config_1.readProjectConfig)();
|
|
88
|
+
if (projectConfig?.appId) {
|
|
89
|
+
appId = projectConfig.appId;
|
|
90
|
+
if (projectConfig.auth?.redirectUrls?.[0]) {
|
|
91
|
+
redirectUri = projectConfig.auth.redirectUrls[0];
|
|
92
|
+
}
|
|
93
|
+
if (projectConfig.auth?.scopes?.length) {
|
|
94
|
+
scopes = projectConfig.auth.scopes;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (!appId) {
|
|
99
|
+
if (process.stdin.isTTY) {
|
|
100
|
+
appId = await container_1.appService.pickApp('Select an app to test:');
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
throw new errors_1.CliError('No local app found.\n' +
|
|
104
|
+
' Run `brevo app scaffold` to set up a project, or pass `--app-id <id>`.\n' +
|
|
105
|
+
' You can also set CLIENT_ID and CLIENT_SECRET in .env.local.');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (appId) {
|
|
109
|
+
const credSpinner = (0, ui_1.createSpinner)('Fetching app credentials...');
|
|
110
|
+
const result = await container_1.appService.resolveAppCredentials(appId);
|
|
111
|
+
credSpinner.stop();
|
|
112
|
+
if (result) {
|
|
113
|
+
if (result.diffs.length > 0) {
|
|
114
|
+
(0, logger_1.logWarn)(`Local credentials for app ${appId} differ from server (${result.diffs.join(', ')}). Updating local cache.`);
|
|
115
|
+
}
|
|
116
|
+
container_1.appService.syncAppCredentials(appId, result.app);
|
|
117
|
+
clientId = clientId || result.app.client_id;
|
|
118
|
+
clientSecret = clientSecret || result.app.client_secret;
|
|
119
|
+
if (!process.env.REDIRECT_URI && result.app.redirect_uris?.[0]) {
|
|
120
|
+
redirectUri = result.app.redirect_uris[0];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (!clientId || !clientSecret) {
|
|
126
|
+
throw new errors_1.CliError('CLIENT_ID and CLIENT_SECRET are required.\n' +
|
|
127
|
+
' Set them in a .env file or as environment variables.\n' +
|
|
128
|
+
` ${en_1.messages.APP_TEST_MISSING_CREDENTIALS}`);
|
|
129
|
+
}
|
|
130
|
+
return { clientId, clientSecret, redirectUri, scopes };
|
|
131
|
+
}
|
|
132
|
+
function buildAuthUrl(clientId, redirectUri, state, scopes) {
|
|
133
|
+
return (`${constants_1.API_BASE}${constants_1.ENDPOINTS.OAUTH_AUTHORIZE}` +
|
|
134
|
+
`?client_id=${encodeURIComponent(clientId)}` +
|
|
135
|
+
`&redirect_uri=${encodeURIComponent(redirectUri)}` +
|
|
136
|
+
`&response_type=code` +
|
|
137
|
+
`&state=${state}` +
|
|
138
|
+
`&scope=${encodeURIComponent(scopes.join(' '))}`);
|
|
139
|
+
}
|
|
140
|
+
async function exchangeCodeForTokens(code, clientId, clientSecret, redirectUri) {
|
|
141
|
+
const tokenResponse = await fetch(`${constants_1.API_BASE}${constants_1.ENDPOINTS.OAUTH_TOKEN}`, {
|
|
142
|
+
method: 'POST',
|
|
143
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
144
|
+
body: new URLSearchParams({
|
|
145
|
+
grant_type: 'authorization_code',
|
|
146
|
+
client_id: clientId,
|
|
147
|
+
client_secret: clientSecret,
|
|
148
|
+
code,
|
|
149
|
+
redirect_uri: redirectUri,
|
|
150
|
+
}).toString(),
|
|
151
|
+
});
|
|
152
|
+
return (await tokenResponse.json());
|
|
153
|
+
}
|
|
154
|
+
async function refreshAccessToken(refreshToken, clientId, clientSecret) {
|
|
155
|
+
const tokenResponse = await fetch(`${constants_1.API_BASE}${constants_1.ENDPOINTS.OAUTH_TOKEN}`, {
|
|
156
|
+
method: 'POST',
|
|
157
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
158
|
+
body: new URLSearchParams({
|
|
159
|
+
grant_type: 'refresh_token',
|
|
160
|
+
client_id: clientId,
|
|
161
|
+
client_secret: clientSecret,
|
|
162
|
+
refresh_token: refreshToken,
|
|
163
|
+
}).toString(),
|
|
164
|
+
});
|
|
165
|
+
return (await tokenResponse.json());
|
|
166
|
+
}
|
|
167
|
+
const browser_1 = require("../../lib/browser");
|
|
168
|
+
// Sanitise untrusted values before embedding in HTML to prevent XSS
|
|
169
|
+
function escapeHtml(str) {
|
|
170
|
+
return str
|
|
171
|
+
.replace(/&/g, '&')
|
|
172
|
+
.replace(/</g, '<')
|
|
173
|
+
.replace(/>/g, '>')
|
|
174
|
+
.replace(/"/g, '"');
|
|
175
|
+
}
|
|
176
|
+
// Inline styles and JS for masked token display with click-to-reveal
|
|
177
|
+
const TOKEN_STYLES = '<style>' +
|
|
178
|
+
'*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}' +
|
|
179
|
+
'body{font-family:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;background:rgb(250,245,227);min-height:100vh;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 16px}' +
|
|
180
|
+
'.page-card{background:#fff;border:1px solid #e3e3e3;border-radius:16px;padding:40px;width:100%;max-width:560px;text-align:center}' +
|
|
181
|
+
'.page-card h2{color:#1b1b1b;font-size:22px;margin-bottom:8px}' +
|
|
182
|
+
'.page-card .subtitle{color:#696969;font-size:14px;margin-bottom:24px}' +
|
|
183
|
+
'.btn-primary{display:inline-block;width:100%;padding:8px 16px;background:#1b1b1b;color:#fff;border:none;border-radius:16px;font-size:16px;font-weight:600;cursor:pointer;text-decoration:none;text-align:center;line-height:24px}' +
|
|
184
|
+
'.btn-primary:hover{background:#2c2c2c}' +
|
|
185
|
+
'a{color:#1b1b1b}' +
|
|
186
|
+
'.token-wrapper{position:relative;margin-top:6px}' +
|
|
187
|
+
'.token-value{display:block;padding:10px;background:#fff;border:1px solid #cfcfcf;border-radius:8px;font-family:monospace;font-size:13px;filter:blur(5px);user-select:none;cursor:pointer;transition:filter 0.2s}' +
|
|
188
|
+
'.token-value.revealed{filter:none;user-select:text;cursor:text}' +
|
|
189
|
+
'.reveal-btn{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background:#1b1b1b;color:#fff;border:none;padding:8px 16px;border-radius:16px;font-size:13px;font-weight:600;cursor:pointer}' +
|
|
190
|
+
'.reveal-btn.hidden{display:none}' +
|
|
191
|
+
'.request-details{text-align:left;margin:16px 0;background:#f5f5f5;border:1px solid #e3e3e3;padding:16px 20px;border-radius:16px;font-size:13px}' +
|
|
192
|
+
'.request-details strong{color:#1b1b1b}' +
|
|
193
|
+
'.request-details dt{font-weight:600;margin-top:8px;color:#1b1b1b}' +
|
|
194
|
+
'.request-details dd{margin:2px 0 0 0;font-family:monospace;word-break:break-all;color:#696969}' +
|
|
195
|
+
'.token-section{text-align:left;margin:16px 0;background:#f5f5f5;border:1px solid #e3e3e3;padding:20px;border-radius:16px;word-break:break-all}' +
|
|
196
|
+
'.footer-text{color:#858585;font-size:12px;margin-top:16px}' +
|
|
197
|
+
'</style>';
|
|
198
|
+
const TOKEN_SCRIPT = '<script>' +
|
|
199
|
+
'document.querySelectorAll(".reveal-btn").forEach(function(btn){' +
|
|
200
|
+
' btn.addEventListener("click",function(){' +
|
|
201
|
+
' var code=btn.parentElement.querySelector(".token-value");' +
|
|
202
|
+
' code.classList.add("revealed");' +
|
|
203
|
+
' btn.classList.add("hidden");' +
|
|
204
|
+
' });' +
|
|
205
|
+
'});' +
|
|
206
|
+
'</script>';
|
|
207
|
+
function maskedTokenBlock(label, value, extra) {
|
|
208
|
+
const extraInfo = extra ? ` (${escapeHtml(extra)})` : '';
|
|
209
|
+
return (`<p><strong>${escapeHtml(label)}</strong>${extraInfo}:</p>` +
|
|
210
|
+
'<div class="token-wrapper">' +
|
|
211
|
+
`<code class="token-value">${escapeHtml(value)}</code>` +
|
|
212
|
+
'<button class="reveal-btn">Click to reveal</button>' +
|
|
213
|
+
'</div>');
|
|
214
|
+
}
|
|
215
|
+
function requestDetailsHtml(clientId, redirectUri, scopes) {
|
|
216
|
+
return ('<div class="request-details">' +
|
|
217
|
+
'<strong>Authorization Request</strong>' +
|
|
218
|
+
'<dl>' +
|
|
219
|
+
`<dt>Client ID</dt><dd>${escapeHtml(clientId)}</dd>` +
|
|
220
|
+
`<dt>Redirect URI</dt><dd>${escapeHtml(redirectUri)}</dd>` +
|
|
221
|
+
`<dt>Scopes</dt><dd>${escapeHtml(scopes.join(' '))}</dd>` +
|
|
222
|
+
'<dt>Response Type</dt><dd>code</dd>' +
|
|
223
|
+
'</dl>' +
|
|
224
|
+
'</div>');
|
|
225
|
+
}
|
|
226
|
+
// HTML page shown in the browser after a successful token exchange
|
|
227
|
+
function successHtml(accessToken, refreshToken, expiresIn, clientId, redirectUri, scopes) {
|
|
228
|
+
return (`<html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Brevo OAuth — Success</title>${TOKEN_STYLES}</head>` +
|
|
229
|
+
'<body>' +
|
|
230
|
+
'<div class="page-card">' +
|
|
231
|
+
'<h2>Authorization successful!</h2>' +
|
|
232
|
+
'<p class="subtitle">Tokens are masked for security. Click to reveal.</p>' +
|
|
233
|
+
requestDetailsHtml(clientId, redirectUri, scopes) +
|
|
234
|
+
'<div class="token-section">' +
|
|
235
|
+
maskedTokenBlock('Access Token', accessToken, `expires in ${expiresIn}s`) +
|
|
236
|
+
'<div style="margin-top:16px">' +
|
|
237
|
+
maskedTokenBlock('Refresh Token', refreshToken) +
|
|
238
|
+
'</div>' +
|
|
239
|
+
'</div>' +
|
|
240
|
+
'<p style="margin-top:16px"><a href="/refresh">Refresh token</a></p>' +
|
|
241
|
+
'</div>' +
|
|
242
|
+
TOKEN_SCRIPT +
|
|
243
|
+
'</body></html>');
|
|
244
|
+
}
|
|
245
|
+
function landingHtml(clientId, redirectUri, scopes) {
|
|
246
|
+
return (`<html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Brevo OAuth Test</title>${TOKEN_STYLES}</head>` +
|
|
247
|
+
'<body>' +
|
|
248
|
+
'<div class="page-card">' +
|
|
249
|
+
'<h2>Brevo OAuth Test</h2>' +
|
|
250
|
+
'<p class="subtitle">The following request will be sent to the partner login:</p>' +
|
|
251
|
+
requestDetailsHtml(clientId, redirectUri, scopes) +
|
|
252
|
+
'<a href="/login" class="btn-primary" style="margin-top:8px">Start OAuth Flow</a>' +
|
|
253
|
+
'</div>' +
|
|
254
|
+
'</body></html>');
|
|
255
|
+
}
|
|
256
|
+
exports.testCommand = (0, command_handler_1.withCommandHandler)(async (options) => {
|
|
257
|
+
let port = options.port || 3009;
|
|
258
|
+
const creds = await resolveCredentials(port, options.appId);
|
|
259
|
+
let { redirectUri } = creds;
|
|
260
|
+
const { clientId, clientSecret, scopes } = creds;
|
|
261
|
+
// Generate CSRF state
|
|
262
|
+
const state = crypto.randomBytes(16).toString('hex');
|
|
263
|
+
// In-memory token store for the session
|
|
264
|
+
let sessionRefreshToken;
|
|
265
|
+
const server = http.createServer(async (req, res) => {
|
|
266
|
+
// CORS headers for localhost dev
|
|
267
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
268
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
269
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
|
|
270
|
+
// Cap request body at 1 MB. The test server only handles OAuth callbacks,
|
|
271
|
+
// which carry everything in the query string — any real body here is
|
|
272
|
+
// either a misconfiguration or an attempt to exhaust memory.
|
|
273
|
+
const MAX_BODY_BYTES = 1024 * 1024;
|
|
274
|
+
// Fast path: reject well-behaved large requests on Content-Length
|
|
275
|
+
// before we ever start reading the body.
|
|
276
|
+
const contentLength = Number.parseInt(req.headers['content-length'] || '', 10);
|
|
277
|
+
if (Number.isFinite(contentLength) && contentLength > MAX_BODY_BYTES) {
|
|
278
|
+
res.writeHead(413, { 'Content-Type': 'text/plain', Connection: 'close' });
|
|
279
|
+
res.end('Request entity too large (max 1 MB).');
|
|
280
|
+
req.destroy();
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
// Slow path: chunked / missing Content-Length — count bytes as they stream in.
|
|
284
|
+
// Always count and always destroy on overflow, even if we've already
|
|
285
|
+
// responded (e.g. /login returns 302 before the body finishes streaming).
|
|
286
|
+
// Only gate the 413 write on the response still being open.
|
|
287
|
+
let bodyBytes = 0;
|
|
288
|
+
req.on('data', (chunk) => {
|
|
289
|
+
bodyBytes += chunk.length;
|
|
290
|
+
if (bodyBytes > MAX_BODY_BYTES) {
|
|
291
|
+
if (!res.writableEnded && !res.headersSent) {
|
|
292
|
+
res.writeHead(413, { 'Content-Type': 'text/plain', Connection: 'close' });
|
|
293
|
+
res.end('Request entity too large (max 1 MB).');
|
|
294
|
+
}
|
|
295
|
+
req.destroy();
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
if (req.method === 'OPTIONS') {
|
|
299
|
+
res.writeHead(204);
|
|
300
|
+
res.end();
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
const url = new URL(req.url || '/', `http://localhost:${port}`);
|
|
304
|
+
if (url.pathname === '/login') {
|
|
305
|
+
const authUrl = buildAuthUrl(clientId, redirectUri, state, scopes);
|
|
306
|
+
res.writeHead(302, { Location: authUrl });
|
|
307
|
+
res.end();
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
if (url.pathname === '/callback' || url.pathname === '/auth/callback') {
|
|
311
|
+
const code = url.searchParams.get('code');
|
|
312
|
+
const returnedState = url.searchParams.get('state');
|
|
313
|
+
if (returnedState !== state) {
|
|
314
|
+
res.writeHead(400, { 'Content-Type': 'text/plain' });
|
|
315
|
+
res.end('Invalid state parameter. Possible CSRF attack.');
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
if (!code) {
|
|
319
|
+
const error = url.searchParams.get('error') || 'unknown';
|
|
320
|
+
res.writeHead(400, { 'Content-Type': 'text/plain' });
|
|
321
|
+
res.end(`Authorization failed: ${error}`);
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
(0, logger_1.logInfo)(`\n ${en_1.messages.APP_TEST_CODE_RECEIVED}`);
|
|
325
|
+
const tokenSpinner = (0, ui_1.createSpinner)('Exchanging code for tokens...');
|
|
326
|
+
try {
|
|
327
|
+
const tokens = await exchangeCodeForTokens(code, clientId, clientSecret, redirectUri);
|
|
328
|
+
tokenSpinner.stop();
|
|
329
|
+
// Body-limit handler or client disconnect may have ended the response
|
|
330
|
+
// while we were awaiting the token exchange — don't write to it again.
|
|
331
|
+
if (res.writableEnded)
|
|
332
|
+
return;
|
|
333
|
+
if (tokens.error || !tokens.access_token) {
|
|
334
|
+
(0, logger_1.logError)(`Token exchange failed: ${tokens.error || 'unknown error'}`);
|
|
335
|
+
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
|
336
|
+
res.end('Token exchange failed.');
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
// Store refresh token so the /refresh endpoint can use it later
|
|
340
|
+
if (tokens.refresh_token) {
|
|
341
|
+
sessionRefreshToken = tokens.refresh_token;
|
|
342
|
+
}
|
|
343
|
+
// Display token status in the terminal (tokens are only visible in the browser)
|
|
344
|
+
process.stdout.write('\n');
|
|
345
|
+
(0, logger_1.logSuccess)(` ${en_1.messages.APP_TEST_ACCESS_TOKEN(tokens.expires_in || 0)}`);
|
|
346
|
+
(0, logger_1.logSuccess)(` ${en_1.messages.APP_TEST_REFRESH_TOKEN_RECEIVED}`);
|
|
347
|
+
// Validate the access token by calling the account endpoint
|
|
348
|
+
try {
|
|
349
|
+
const accountResponse = await fetch(`${constants_1.API_BASE}/v3/account`, {
|
|
350
|
+
headers: {
|
|
351
|
+
Authorization: `Bearer ${tokens.access_token}`,
|
|
352
|
+
Accept: 'application/json',
|
|
353
|
+
},
|
|
354
|
+
});
|
|
355
|
+
const account = (await accountResponse.json());
|
|
356
|
+
if (account.email) {
|
|
357
|
+
(0, logger_1.logSuccess)(`Connection verified — ${account.email}`);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
catch {
|
|
361
|
+
// Non-critical — verification is best-effort
|
|
362
|
+
}
|
|
363
|
+
// Let the user know tokens are also visible in the browser
|
|
364
|
+
process.stdout.write('\n');
|
|
365
|
+
(0, logger_1.logInfo)(` ${en_1.messages.APP_TEST_TOKENS_IN_BROWSER(port)}`);
|
|
366
|
+
(0, logger_1.logInfo)(` ${en_1.messages.APP_TEST_TOKEN_REFRESH_URL(port)}`);
|
|
367
|
+
(0, logger_1.logInfo)(` ${en_1.messages.APP_TEST_COMPLETE}\n`);
|
|
368
|
+
// Serve success page with tokens visible in the browser
|
|
369
|
+
res.writeHead(200, {
|
|
370
|
+
'Content-Type': 'text/html',
|
|
371
|
+
'Cache-Control': 'no-store, no-cache, must-revalidate',
|
|
372
|
+
Pragma: 'no-cache',
|
|
373
|
+
Expires: '0',
|
|
374
|
+
});
|
|
375
|
+
res.end(successHtml(tokens.access_token, tokens.refresh_token || '', tokens.expires_in || 0, clientId, redirectUri, scopes));
|
|
376
|
+
}
|
|
377
|
+
catch (err) {
|
|
378
|
+
tokenSpinner.stop();
|
|
379
|
+
(0, logger_1.logError)('Token exchange failed', err);
|
|
380
|
+
if (!res.writableEnded) {
|
|
381
|
+
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
|
382
|
+
res.end('Token exchange failed.');
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
// Token refresh endpoint — exchanges the stored refresh token for a new access token
|
|
388
|
+
if (url.pathname === '/refresh') {
|
|
389
|
+
if (!sessionRefreshToken) {
|
|
390
|
+
res.writeHead(400, { 'Content-Type': 'text/plain' });
|
|
391
|
+
res.end('No refresh token available. Complete the OAuth flow first.');
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
const refreshSpinner = (0, ui_1.createSpinner)('Refreshing access token...');
|
|
395
|
+
try {
|
|
396
|
+
const tokens = await refreshAccessToken(sessionRefreshToken, clientId, clientSecret);
|
|
397
|
+
refreshSpinner.stop();
|
|
398
|
+
if (res.writableEnded)
|
|
399
|
+
return;
|
|
400
|
+
if (tokens.error || !tokens.access_token) {
|
|
401
|
+
(0, logger_1.logError)(` Token refresh failed: ${tokens.error || 'unknown error'}`);
|
|
402
|
+
(0, logger_1.logInfo)(' Re-authenticate by visiting /login\n');
|
|
403
|
+
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
|
404
|
+
res.end(`Token refresh failed: ${tokens.error || 'unknown error'}. Re-authenticate at /login.`);
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
if (tokens.refresh_token) {
|
|
408
|
+
sessionRefreshToken = tokens.refresh_token;
|
|
409
|
+
}
|
|
410
|
+
(0, logger_1.logSuccess)(` ${en_1.messages.APP_TEST_TOKEN_REFRESHED(tokens.expires_in || 0)}\n`);
|
|
411
|
+
res.writeHead(200, {
|
|
412
|
+
'Content-Type': 'text/html',
|
|
413
|
+
'Cache-Control': 'no-store, no-cache, must-revalidate',
|
|
414
|
+
Pragma: 'no-cache',
|
|
415
|
+
Expires: '0',
|
|
416
|
+
});
|
|
417
|
+
res.end(`<html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Brevo OAuth — Token Refreshed</title>${TOKEN_STYLES}</head>` +
|
|
418
|
+
'<body>' +
|
|
419
|
+
'<div class="page-card">' +
|
|
420
|
+
'<h2>Token refreshed!</h2>' +
|
|
421
|
+
'<p class="subtitle">Click to reveal the token.</p>' +
|
|
422
|
+
'<div class="token-section">' +
|
|
423
|
+
maskedTokenBlock('Access Token', tokens.access_token, `expires in ${tokens.expires_in}s`) +
|
|
424
|
+
'</div>' +
|
|
425
|
+
'<p class="footer-text">You can close this window and return to the terminal.</p>' +
|
|
426
|
+
'</div>' +
|
|
427
|
+
TOKEN_SCRIPT +
|
|
428
|
+
'</body></html>');
|
|
429
|
+
}
|
|
430
|
+
catch (err) {
|
|
431
|
+
refreshSpinner.stop();
|
|
432
|
+
(0, logger_1.logError)(' Token refresh failed', err);
|
|
433
|
+
(0, logger_1.logInfo)(' Re-authenticate by visiting /login\n');
|
|
434
|
+
if (!res.writableEnded) {
|
|
435
|
+
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
|
436
|
+
res.end('Token refresh failed. Re-authenticate at /login.');
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
// Default route
|
|
442
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
443
|
+
res.end(landingHtml(clientId, redirectUri, scopes));
|
|
444
|
+
});
|
|
445
|
+
server.setTimeout(30000);
|
|
446
|
+
// Handle port in use — retry with next port
|
|
447
|
+
server.on('error', (err) => {
|
|
448
|
+
if (err.code === 'EADDRINUSE') {
|
|
449
|
+
port++;
|
|
450
|
+
(0, logger_1.logInfo)(` ${en_1.messages.APP_TEST_PORT_IN_USE(port - 1)} Trying port ${port}...`);
|
|
451
|
+
redirectUri = `http://localhost:${port}/auth/callback`;
|
|
452
|
+
server.listen(port, '127.0.0.1');
|
|
453
|
+
}
|
|
454
|
+
else {
|
|
455
|
+
(0, logger_1.logError)(`Server error: ${err.message}`);
|
|
456
|
+
server.close();
|
|
457
|
+
throw new errors_1.CliError(`Server error: ${err.message}`);
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
await new Promise((resolve) => {
|
|
461
|
+
// Save and remove global signal handlers so they don't call
|
|
462
|
+
// process.exit() while the test server is running
|
|
463
|
+
const globalSigint = process.rawListeners('SIGINT');
|
|
464
|
+
const globalSigterm = process.rawListeners('SIGTERM');
|
|
465
|
+
process.removeAllListeners('SIGINT');
|
|
466
|
+
process.removeAllListeners('SIGTERM');
|
|
467
|
+
server.listen(port, '127.0.0.1', () => {
|
|
468
|
+
(0, logger_1.logInfo)(`\n ${en_1.messages.APP_TEST_STARTING(port)}`);
|
|
469
|
+
(0, logger_1.logInfo)(` ${en_1.messages.APP_TEST_REDIRECT_URI(redirectUri)}`);
|
|
470
|
+
(0, logger_1.logInfo)(` ${en_1.messages.APP_TEST_BROWSER_OPEN}`);
|
|
471
|
+
(0, logger_1.logInfo)(` ${en_1.messages.APP_TEST_WAITING}\n`);
|
|
472
|
+
(0, browser_1.openBrowser)(`http://localhost:${port}/login`);
|
|
473
|
+
});
|
|
474
|
+
// Graceful shutdown — close server then restore global handlers
|
|
475
|
+
const onSignal = () => {
|
|
476
|
+
server.close(() => {
|
|
477
|
+
process.stdout.write('\n');
|
|
478
|
+
(0, logger_1.logInfo)(' Server stopped.\n');
|
|
479
|
+
// Restore global signal handlers
|
|
480
|
+
for (const fn of globalSigint)
|
|
481
|
+
process.on('SIGINT', fn);
|
|
482
|
+
for (const fn of globalSigterm)
|
|
483
|
+
process.on('SIGTERM', fn);
|
|
484
|
+
resolve();
|
|
485
|
+
});
|
|
486
|
+
process.removeListener('SIGINT', onSignal);
|
|
487
|
+
process.removeListener('SIGTERM', onSignal);
|
|
488
|
+
};
|
|
489
|
+
process.on('SIGINT', onSignal);
|
|
490
|
+
process.on('SIGTERM', onSignal);
|
|
491
|
+
// Also resolve if server closes for any other reason
|
|
492
|
+
server.on('close', () => resolve());
|
|
493
|
+
});
|
|
494
|
+
});
|
|
495
|
+
//# sourceMappingURL=test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../../src/commands/app/test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/app/update.ts"],"names":[],"mappings":"AAsBA,eAAO,MAAM,aAAa,kDAqPxB,CAAC"}
|