@anmiles/google-api-wrapper 7.0.1 → 7.0.2

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 CHANGED
@@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [7.0.2](../../tags/v7.0.2) - 2023-04-22
9
+ ### Changed
10
+ - Show instructions in the browser to prevent direct opening profile-oriented pages in wrong browsers
11
+
8
12
  ## [7.0.1](../../tags/v7.0.1) - 2023-04-22
9
13
  ### Changed
10
14
  - Compatibility for `open` package
@@ -1,27 +1,4 @@
1
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 (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
4
  };
@@ -29,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
29
6
  exports.getCredentials = exports.getSecrets = void 0;
30
7
  const http_1 = __importDefault(require("http"));
31
8
  const server_destroy_1 = __importDefault(require("server-destroy"));
32
- const colorette = __importStar(require("colorette"));
33
9
  const open_1 = __importDefault(require("open"));
34
10
  const jsonLib_1 = require("./jsonLib");
35
11
  const logger_1 = require("./logger");
@@ -37,6 +13,7 @@ const paths_1 = require("./paths");
37
13
  const secrets_1 = __importDefault(require("./secrets"));
38
14
  exports.default = { getScopes, getSecrets, getCredentials, validateCredentials, createCredentials, checkSecrets, getSecretsError, getScopesError };
39
15
  const callbackPort = 6006;
16
+ const startURI = `http://localhost:${callbackPort}/`;
40
17
  const callbackURI = `http://localhost:${callbackPort}/oauthcallback`;
41
18
  const tokenExpiration = 7 * 24 * 60 * 60 * 1000;
42
19
  function getScopes() {
@@ -76,28 +53,34 @@ async function createCredentials(profile, auth, options) {
76
53
  scope,
77
54
  });
78
55
  const server = http_1.default.createServer(async (request, response) => {
79
- response.end('<h1>Please close this page and return to application. Wait for application to be finished automatically.</h1>');
80
- if (request.url) {
81
- const url = new URL(`http://${request.headers.host}${request.url}`);
82
- const code = url.searchParams.get('code');
83
- if (!code) {
84
- return;
85
- }
86
- server.destroy();
87
- const { tokens } = await auth.getToken(code);
88
- resolve(tokens);
56
+ if (!request.url) {
57
+ response.end('');
58
+ return;
59
+ }
60
+ const url = new URL(`http://${request.headers.host}${request.url}`);
61
+ const code = url.searchParams.get('code');
62
+ if (!code) {
63
+ response.end(formatMessage(`Please open <a href="${authUrl}">this link</a> in a browser that belongs to <strong>${profile}</strong> google profile`));
64
+ return;
89
65
  }
66
+ response.end(formatMessage('Please close this page and return to application'));
67
+ server.destroy();
68
+ const { tokens } = await auth.getToken(code);
69
+ resolve(tokens);
90
70
  });
91
71
  (0, server_destroy_1.default)(server);
92
72
  server.listen(callbackPort);
93
- if (options === null || options === void 0 ? void 0 : options.temporary) {
94
- (0, logger_1.info)(`Please open ${colorette.yellow(authUrl)} in your browser using google profile for ${colorette.yellow(profile)} and allow access to ${colorette.yellow(scope.join(','))}`);
95
- }
96
- else {
97
- (0, open_1.default)(authUrl);
98
- }
73
+ (0, logger_1.warn)('Please check your browser for further actions');
74
+ (0, open_1.default)(startURI);
99
75
  });
100
76
  }
77
+ function formatMessage(message) {
78
+ return [
79
+ '<div style="margin: 1em auto; padding: 0 1em; border: 1px solid black; max-width: 600px; text-align: center; font-family: Arial, sans-serif">',
80
+ `<p>${message}</p>`,
81
+ '</div>',
82
+ ].join('\n');
83
+ }
101
84
  function checkSecrets(profile, secretsObject, secretsFile) {
102
85
  if (secretsObject.web.redirect_uris[0] === callbackURI) {
103
86
  return true;
@@ -1 +1 @@
1
- {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/lib/secrets.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/lib/secrets.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anmiles/google-api-wrapper",
3
- "version": "7.0.1",
3
+ "version": "7.0.2",
4
4
  "description": "Provides quick interface for getting google API data",
5
5
  "keywords": [
6
6
  "google",
@@ -41,7 +41,9 @@ jest.mock<Partial<typeof colorette>>('colorette', () => ({
41
41
  yellow : jest.fn().mockImplementation((text) => `yellow:${text}`),
42
42
  }));
43
43
 
44
- jest.mock<Partial<typeof open>>('open', () => jest.fn());
44
+ jest.mock('open', () => jest.fn().mockImplementation((url: string) => {
45
+ willOpen(url.replace('http://localhost:6006', ''));
46
+ }));
45
47
 
46
48
  jest.mock<Partial<typeof jsonLib>>('../jsonLib', () => ({
47
49
  getJSON : jest.fn().mockImplementation(() => json),
@@ -49,7 +51,7 @@ jest.mock<Partial<typeof jsonLib>>('../jsonLib', () => ({
49
51
  }));
50
52
 
51
53
  jest.mock<Partial<typeof logger>>('../logger', () => ({
52
- info : jest.fn(),
54
+ warn : jest.fn(),
53
55
  error : jest.fn().mockImplementation((error) => {
54
56
  throw error;
55
57
  }) as jest.Mock<never, any>,
@@ -96,8 +98,6 @@ const auth = {
96
98
  getToken : jest.fn().mockResolvedValue({ tokens : credentialsJSON }),
97
99
  } as unknown as GoogleApis.Common.OAuth2Client;
98
100
 
99
- let request: http.IncomingMessage;
100
-
101
101
  const response = {
102
102
  end : jest.fn(),
103
103
  } as unknown as http.ServerResponse;
@@ -107,6 +107,16 @@ let serverCallback: (
107
107
  response: http.ServerResponse
108
108
  ) => Promise<typeof credentialsJSON>;
109
109
 
110
+ function willOpen(url: string | undefined, timeout?: number) {
111
+ setTimeout(async () => {
112
+ await serverCallback({
113
+ url,
114
+ headers : {
115
+ host : 'localhost:6006',
116
+ },
117
+ } as http.IncomingMessage, response);
118
+ }, timeout || 0);
119
+ }
110
120
  let closedTime: number;
111
121
 
112
122
  const on = jest.fn().mockImplementation((event: string, listener: (...args: any[]) => void) => {
@@ -285,23 +295,10 @@ describe('src/lib/secrets', () => {
285
295
  });
286
296
 
287
297
  describe('createCredentials', () => {
288
- function willOpen(request: http.IncomingMessage, timeout: number) {
289
- setTimeout(async () => {
290
- await serverCallback(request, response);
291
- }, timeout);
292
- }
293
-
294
- beforeEach(() => {
295
- request = {
296
- url : `/request.url?code=${code}`,
297
- headers : {
298
- host : 'localhost:6006',
299
- },
300
- } as http.IncomingMessage;
301
- });
298
+ const tokenUrl = `/request.url?code=${code}`;
302
299
 
303
300
  it('should generate authUrl', async () => {
304
- willOpen(request, 100);
301
+ willOpen(tokenUrl, 100);
305
302
 
306
303
  await original.createCredentials(profile, auth);
307
304
 
@@ -316,7 +313,7 @@ describe('src/lib/secrets', () => {
316
313
  });
317
314
 
318
315
  it('should generate authUrl with custom scopes', async () => {
319
- willOpen(request, 100);
316
+ willOpen(tokenUrl, 100);
320
317
 
321
318
  await original.createCredentials(profile, auth, { scopes : [ 'scope1', 'scope2' ] });
322
319
 
@@ -328,7 +325,7 @@ describe('src/lib/secrets', () => {
328
325
  });
329
326
 
330
327
  it('should create server on 6006 port', async () => {
331
- willOpen(request, 100);
328
+ willOpen(tokenUrl, 100);
332
329
 
333
330
  await original.createCredentials(profile, auth);
334
331
 
@@ -336,43 +333,43 @@ describe('src/lib/secrets', () => {
336
333
  expect(listen).toBeCalledWith(6006);
337
334
  });
338
335
 
339
- it('should open browser page without prompt if this is permanent request that tends to save credentials in the file', async () => {
340
- willOpen(request, 100);
336
+ it('should open browser page and warn about it', async () => {
337
+ willOpen(tokenUrl, 100);
341
338
 
342
339
  await original.createCredentials(profile, auth);
343
340
 
344
- expect(open).toBeCalledWith('https://authUrl');
345
- expect(logger.info).not.toBeCalled();
341
+ expect(open).toBeCalledWith('http://localhost:6006/');
342
+ expect(logger.warn).toBeCalledWith('Please check your browser for further actions');
346
343
  });
347
344
 
348
- it('should ask to open browser page', async () => {
349
- willOpen(request, 100);
345
+ it('should show nothing on the browser page if request.url is empty', async () => {
346
+ willOpen('', 100);
347
+ willOpen(tokenUrl, 200);
350
348
 
351
- await original.createCredentials(profile, auth, { temporary : true });
349
+ await original.createCredentials(profile, auth);
352
350
 
353
- expect(open).not.toBeCalled();
354
- expect(logger.info).toBeCalledWith(`Please open yellow:https://authUrl in your browser using google profile for yellow:${profile} and allow access to yellow:https://www.googleapis.com/auth/calendar.calendars.readonly,https://www.googleapis.com/auth/calendar.events.readonly`);
351
+ expect(response.end).toBeCalledWith('');
355
352
  });
356
353
 
357
- it('should ask to open browser page with custom scopes', async () => {
358
- willOpen(request, 100);
354
+ it('should show opening instructions if opened the home page', async () => {
355
+ willOpen('/', 100);
356
+ willOpen(tokenUrl, 200);
359
357
 
360
- await original.createCredentials(profile, auth, { temporary : true, scopes : [ 'scope1', 'scope2' ] });
358
+ await original.createCredentials(profile, auth);
361
359
 
362
- expect(open).not.toBeCalled();
363
- expect(logger.info).toBeCalledWith(`Please open yellow:https://authUrl in your browser using google profile for yellow:${profile} and allow access to yellow:scope1,scope2`);
360
+ expect(response.end).toBeCalledWith(`<div style="margin: 1em auto; padding: 0 1em; border: 1px solid black; max-width: 600px; text-align: center; font-family: Arial, sans-serif">\n<p>Please open <a href="${authUrl}">this link</a> in a browser that belongs to <strong>${profile}</strong> google profile</p>\n</div>`);
364
361
  });
365
362
 
366
363
  it('should ask to close webpage', async () => {
367
- willOpen(request, 100);
364
+ willOpen(tokenUrl, 100);
368
365
 
369
366
  await original.createCredentials(profile, auth);
370
367
 
371
- expect(response.end).toBeCalledWith('<h1>Please close this page and return to application. Wait for application to be finished automatically.</h1>');
368
+ expect(response.end).toBeCalledWith('<div style="margin: 1em auto; padding: 0 1em; border: 1px solid black; max-width: 600px; text-align: center; font-family: Arial, sans-serif">\n<p>Please close this page and return to application</p>\n</div>');
372
369
  });
373
370
 
374
371
  it('should close server and destroy all connections if request.url is truthy', async () => {
375
- willOpen(request, 100);
372
+ willOpen(tokenUrl, 100);
376
373
 
377
374
  await original.createCredentials(profile, auth);
378
375
 
@@ -384,12 +381,10 @@ describe('src/lib/secrets', () => {
384
381
  it('should only resolve when request.url is truthy', async () => {
385
382
  const emptyRequestTime = 100;
386
383
  const requestTime = 200;
387
- const emptyRequest = { ...request } as http.IncomingMessage;
388
- emptyRequest.url = undefined;
389
384
 
390
385
  const before = new Date().getTime();
391
- willOpen(emptyRequest, emptyRequestTime);
392
- willOpen(request, requestTime);
386
+ willOpen(undefined, emptyRequestTime);
387
+ willOpen(tokenUrl, requestTime);
393
388
 
394
389
  const result = await original.createCredentials(profile, auth);
395
390
  const after = new Date().getTime();
@@ -403,12 +398,10 @@ describe('src/lib/secrets', () => {
403
398
  it('should only resolve when request.url contains no code', async () => {
404
399
  const noCodeRequestTime = 100;
405
400
  const requestTime = 200;
406
- const noCodeRequest = { ...request } as http.IncomingMessage;
407
- noCodeRequest.url = '/request.url?param=value';
408
401
 
409
402
  const before = new Date().getTime();
410
- willOpen(noCodeRequest, noCodeRequestTime);
411
- willOpen(request, requestTime);
403
+ willOpen('/request.url?param=value', noCodeRequestTime);
404
+ willOpen(tokenUrl, requestTime);
412
405
 
413
406
  const result = await original.createCredentials(profile, auth);
414
407
  const after = new Date().getTime();
@@ -420,7 +413,7 @@ describe('src/lib/secrets', () => {
420
413
  });
421
414
 
422
415
  it('should return credentials JSON', async () => {
423
- willOpen(request, 100);
416
+ willOpen(tokenUrl, 100);
424
417
 
425
418
  const result = await original.createCredentials(profile, auth);
426
419
 
@@ -1,11 +1,10 @@
1
1
  import http from 'http';
2
2
  import enableDestroy from 'server-destroy';
3
- import * as colorette from 'colorette';
4
3
  import open from 'open';
5
4
  import type GoogleApis from 'googleapis';
6
5
  import type { Secrets, AuthOptions } from '../types';
7
6
  import { getJSON, getJSONAsync } from './jsonLib';
8
- import { info, error } from './logger';
7
+ import { warn, error } from './logger';
9
8
  import { getScopesFile, getSecretsFile, getCredentialsFile } from './paths';
10
9
 
11
10
  import secrets from './secrets';
@@ -14,6 +13,7 @@ export { getSecrets, getCredentials };
14
13
  export default { getScopes, getSecrets, getCredentials, validateCredentials, createCredentials, checkSecrets, getSecretsError, getScopesError };
15
14
 
16
15
  const callbackPort = 6006;
16
+ const startURI = `http://localhost:${callbackPort}/`;
17
17
  const callbackURI = `http://localhost:${callbackPort}/oauthcallback`;
18
18
  const tokenExpiration = 7 * 24 * 60 * 60 * 1000;
19
19
 
@@ -61,33 +61,40 @@ async function createCredentials(profile: string, auth: GoogleApis.Auth.OAuth2Cl
61
61
  });
62
62
 
63
63
  const server = http.createServer(async (request, response) => {
64
- response.end('<h1>Please close this page and return to application. Wait for application to be finished automatically.</h1>');
65
-
66
- if (request.url) {
67
- const url = new URL(`http://${request.headers.host}${request.url}`);
68
- const code = url.searchParams.get('code');
64
+ if (!request.url) {
65
+ response.end('');
66
+ return;
67
+ }
69
68
 
70
- if (!code) {
71
- return;
72
- }
69
+ const url = new URL(`http://${request.headers.host}${request.url}`);
70
+ const code = url.searchParams.get('code');
73
71
 
74
- server.destroy();
75
- const { tokens } = await auth.getToken(code);
76
- resolve(tokens);
72
+ if (!code) {
73
+ response.end(formatMessage(`Please open <a href="${authUrl}">this link</a> in a browser that belongs to <strong>${profile}</strong> google profile`));
74
+ return;
77
75
  }
76
+
77
+ response.end(formatMessage('Please close this page and return to application'));
78
+ server.destroy();
79
+ const { tokens } = await auth.getToken(code);
80
+ resolve(tokens);
78
81
  });
79
82
 
80
83
  enableDestroy(server);
81
84
  server.listen(callbackPort);
82
-
83
- if (options?.temporary) {
84
- info(`Please open ${colorette.yellow(authUrl)} in your browser using google profile for ${colorette.yellow(profile)} and allow access to ${colorette.yellow(scope.join(','))}`);
85
- } else {
86
- open(authUrl);
87
- }
85
+ warn('Please check your browser for further actions');
86
+ open(startURI);
88
87
  });
89
88
  }
90
89
 
90
+ function formatMessage(message: string): string {
91
+ return [
92
+ '<div style="margin: 1em auto; padding: 0 1em; border: 1px solid black; max-width: 600px; text-align: center; font-family: Arial, sans-serif">',
93
+ `<p>${message}</p>`,
94
+ '</div>',
95
+ ].join('\n');
96
+ }
97
+
91
98
  function checkSecrets(profile: string, secretsObject: Secrets, secretsFile: string): true | void {
92
99
  if (secretsObject.web.redirect_uris[0] === callbackURI) {
93
100
  return true;