@runtypelabs/cli 1.2.1 → 1.3.0

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/dist/index.js CHANGED
@@ -151,6 +151,7 @@ var CallbackServer = class {
151
151
  codeResolve;
152
152
  codeReject;
153
153
  codePromise;
154
+ expectedState;
154
155
  constructor() {
155
156
  this.app = express();
156
157
  this.codePromise = new Promise((resolve, reject) => {
@@ -158,12 +159,23 @@ var CallbackServer = class {
158
159
  this.codeReject = reject;
159
160
  });
160
161
  this.app.get("/callback", (req, res) => {
161
- const { token, error } = req.query;
162
+ const { token, code, state, error } = req.query;
162
163
  if (error) {
163
164
  res.send(this.errorHTML(error));
164
165
  this.codeReject(new Error(error));
165
166
  return;
166
167
  }
168
+ if (code) {
169
+ if (this.expectedState && state !== this.expectedState) {
170
+ res.send(this.errorHTML("State parameter mismatch - possible CSRF attack"));
171
+ this.codeReject(new Error("OAuth2 state parameter mismatch"));
172
+ return;
173
+ }
174
+ res.send(this.successHTML());
175
+ this.codeResolve(code);
176
+ setTimeout(() => this.stop(), 1e3);
177
+ return;
178
+ }
167
179
  if (!token) {
168
180
  res.send(this.errorHTML("No authentication token received"));
169
181
  this.codeReject(new Error("No authentication token received"));
@@ -177,6 +189,10 @@ var CallbackServer = class {
177
189
  res.json({ status: "ok" });
178
190
  });
179
191
  }
192
+ /** Set expected state parameter for OAuth2 CSRF validation */
193
+ setExpectedState(state) {
194
+ this.expectedState = state;
195
+ }
180
196
  async start(port = 8765) {
181
197
  return new Promise((resolveStart, rejectStart) => {
182
198
  this.server = this.app.listen(port, () => {
@@ -382,6 +398,9 @@ var CallbackServer = class {
382
398
  </body>
383
399
  </html>`;
384
400
  }
401
+ escapeHtml(str) {
402
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
403
+ }
385
404
  errorHTML(error) {
386
405
  return `
387
406
  <!DOCTYPE html>
@@ -440,7 +459,7 @@ var CallbackServer = class {
440
459
  <div class="error-icon">\u2715</div>
441
460
  <h1>Authentication Failed</h1>
442
461
  <p>There was an error during authentication.</p>
443
- <div class="error-details">${error}</div>
462
+ <div class="error-details">${this.escapeHtml(error)}</div>
444
463
  </div>
445
464
  </body>
446
465
  </html>