@anmiles/google-api-wrapper 7.0.2 → 7.0.3

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.3](../../tags/v7.0.3) - 2023-04-22
9
+ ### Changed
10
+ - Always require refresh token for permanent credentials
11
+
8
12
  ## [7.0.2](../../tags/v7.0.2) - 2023-04-22
9
13
  ### Changed
10
14
  - Show instructions in the browser to prevent direct opening profile-oriented pages in wrong browsers
@@ -1,4 +1,4 @@
1
- export { getJSON, getJSONAsync, writeJSON };
1
+ export { getJSON, getJSONAsync, writeJSON, readJSON };
2
2
  declare const _default: {
3
3
  getJSON: typeof getJSON;
4
4
  getJSONAsync: typeof getJSONAsync;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.writeJSON = exports.getJSONAsync = exports.getJSON = void 0;
6
+ exports.readJSON = exports.writeJSON = exports.getJSONAsync = exports.getJSON = void 0;
7
7
  const fs_1 = __importDefault(require("fs"));
8
8
  const logger_1 = require("./logger");
9
9
  const paths_1 = require("./paths");
@@ -46,6 +46,7 @@ function readJSON(filename) {
46
46
  const jsonString = fs_1.default.readFileSync(filename).toString();
47
47
  return JSON.parse(jsonString);
48
48
  }
49
+ exports.readJSON = readJSON;
49
50
  function checkJSON(filename, json) {
50
51
  if (json) {
51
52
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"jsonLib.js","sourceRoot":"","sources":["../../src/lib/jsonLib.ts"],"names":[],"mappings":";;;;;;AAAA,4CAAoB;AACpB,qCAAiC;AACjC,mCAAqC;AAErC,wDAAgC;AAGhC,kBAAe,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AAEzE,SAAS,OAAO,CAAI,QAAgB,EAAE,cAA8C,EAAE,YAAmC;IACxH,IAAI,YAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;QAC5B,MAAM,IAAI,GAAG,iBAAO,CAAC,QAAQ,CAAI,QAAQ,CAAC,CAAC;QAE3C,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE;YACxC,OAAO,IAAI,CAAC;SACZ;KACD;IAED,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;IAC9B,iBAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAClC,IAAA,kBAAU,EAAC,QAAQ,CAAC,CAAC;IACrB,iBAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAClC,OAAO,IAAI,CAAC;AACb,CAAC;AAjBQ,0BAAO;AAmBhB,KAAK,UAAU,YAAY,CAAI,QAAgB,EAAE,mBAAqC,EAAE,iBAAiD;IACxI,IAAI,YAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;QAC5B,MAAM,IAAI,GAAG,iBAAO,CAAC,QAAQ,CAAI,QAAQ,CAAC,CAAC;QAE3C,IAAI,CAAC,iBAAiB,IAAI,MAAM,iBAAiB,CAAC,IAAI,CAAC,EAAE;YACxD,OAAO,IAAI,CAAC;SACZ;KACD;IAED,MAAM,IAAI,GAAG,MAAM,mBAAmB,EAAE,CAAC;IACzC,iBAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAClC,IAAA,kBAAU,EAAC,QAAQ,CAAC,CAAC;IACrB,iBAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAClC,OAAO,IAAI,CAAC;AACb,CAAC;AAjCiB,oCAAY;AAmC9B,SAAS,SAAS,CAAI,QAAgB,EAAE,IAAO;IAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACtD,YAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;AACxC,CAAC;AAtC+B,8BAAS;AAwCzC,SAAS,QAAQ,CAAI,QAAgB;IACpC,MAAM,UAAU,GAAG,YAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;IACxD,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAM,CAAC;AACpC,CAAC;AAED,SAAS,SAAS,CAAI,QAAgB,EAAE,IAAO;IAC9C,IAAI,IAAI,EAAE;QACT,OAAO;KACP;IACD,IAAA,cAAK,EAAC,QAAQ,QAAQ,sGAAsG,CAAC,CAAC;AAC/H,CAAC"}
1
+ {"version":3,"file":"jsonLib.js","sourceRoot":"","sources":["../../src/lib/jsonLib.ts"],"names":[],"mappings":";;;;;;AAAA,4CAAoB;AACpB,qCAAiC;AACjC,mCAAqC;AAErC,wDAAgC;AAGhC,kBAAe,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AAEzE,SAAS,OAAO,CAAI,QAAgB,EAAE,cAA8C,EAAE,YAAmC;IACxH,IAAI,YAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;QAC5B,MAAM,IAAI,GAAG,iBAAO,CAAC,QAAQ,CAAI,QAAQ,CAAC,CAAC;QAE3C,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE;YACxC,OAAO,IAAI,CAAC;SACZ;KACD;IAED,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;IAC9B,iBAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAClC,IAAA,kBAAU,EAAC,QAAQ,CAAC,CAAC;IACrB,iBAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAClC,OAAO,IAAI,CAAC;AACb,CAAC;AAjBQ,0BAAO;AAmBhB,KAAK,UAAU,YAAY,CAAI,QAAgB,EAAE,mBAAqC,EAAE,iBAAiD;IACxI,IAAI,YAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;QAC5B,MAAM,IAAI,GAAG,iBAAO,CAAC,QAAQ,CAAI,QAAQ,CAAC,CAAC;QAE3C,IAAI,CAAC,iBAAiB,IAAI,MAAM,iBAAiB,CAAC,IAAI,CAAC,EAAE;YACxD,OAAO,IAAI,CAAC;SACZ;KACD;IAED,MAAM,IAAI,GAAG,MAAM,mBAAmB,EAAE,CAAC;IACzC,iBAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAClC,IAAA,kBAAU,EAAC,QAAQ,CAAC,CAAC;IACrB,iBAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAClC,OAAO,IAAI,CAAC;AACb,CAAC;AAjCiB,oCAAY;AAmC9B,SAAS,SAAS,CAAI,QAAgB,EAAE,IAAO;IAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACtD,YAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;AACxC,CAAC;AAtC+B,8BAAS;AAwCzC,SAAS,QAAQ,CAAI,QAAgB;IACpC,MAAM,UAAU,GAAG,YAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;IACxD,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAM,CAAC;AACpC,CAAC;AA3C0C,4BAAQ;AA6CnD,SAAS,SAAS,CAAI,QAAgB,EAAE,IAAO;IAC9C,IAAI,IAAI,EAAE;QACT,OAAO;KACP;IACD,IAAA,cAAK,EAAC,QAAQ,QAAQ,sGAAsG,CAAC,CAAC;AAC/H,CAAC"}
@@ -30,15 +30,25 @@ function getSecrets(profile) {
30
30
  exports.getSecrets = getSecrets;
31
31
  async function getCredentials(profile, auth, options) {
32
32
  const credentialsFile = (0, paths_1.getCredentialsFile)(profile);
33
- return (options === null || options === void 0 ? void 0 : options.temporary)
34
- ? secrets_1.default.createCredentials(profile, auth, options)
35
- : (0, jsonLib_1.getJSONAsync)(credentialsFile, () => secrets_1.default.createCredentials(profile, auth, options), secrets_1.default.validateCredentials);
33
+ if (options === null || options === void 0 ? void 0 : options.temporary) {
34
+ return secrets_1.default.createCredentials(profile, auth, options);
35
+ }
36
+ return (0, jsonLib_1.getJSONAsync)(credentialsFile, async () => {
37
+ // eslint-disable-next-line camelcase
38
+ const refresh_token = (0, paths_1.ensureFile)(credentialsFile) ? (0, jsonLib_1.readJSON)(credentialsFile).refresh_token : undefined;
39
+ const credentials = await secrets_1.default.createCredentials(profile, auth, options);
40
+ // eslint-disable-next-line camelcase
41
+ return { refresh_token, ...credentials };
42
+ }, secrets_1.default.validateCredentials);
36
43
  }
37
44
  exports.getCredentials = getCredentials;
38
45
  async function validateCredentials(credentials) {
39
46
  if (!credentials.access_token) {
40
47
  return false;
41
48
  }
49
+ if (!credentials.refresh_token) {
50
+ return false;
51
+ }
42
52
  if (!credentials.expiry_date) {
43
53
  return true;
44
54
  }
@@ -50,6 +60,7 @@ async function createCredentials(profile, auth, options) {
50
60
  const authUrl = auth.generateAuthUrl({
51
61
  // eslint-disable-next-line camelcase
52
62
  access_type: 'offline',
63
+ prompt: (options === null || options === void 0 ? void 0 : options.temporary) ? undefined : 'consent',
53
64
  scope,
54
65
  });
55
66
  const server = http_1.default.createServer(async (request, response) => {
@@ -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.2",
3
+ "version": "7.0.3",
4
4
  "description": "Provides quick interface for getting google API data",
5
5
  "keywords": [
6
6
  "google",
@@ -5,6 +5,7 @@ import open from 'open';
5
5
  import type GoogleApis from 'googleapis';
6
6
  import jsonLib from '../jsonLib';
7
7
  import logger from '../logger';
8
+ import paths from '../paths';
8
9
  import type { Secrets } from '../../types';
9
10
 
10
11
  import secrets from '../secrets';
@@ -14,7 +15,7 @@ jest.mock<typeof secrets>('../secrets', () => ({
14
15
  getSecrets : jest.fn().mockImplementation(() => secretsJSON),
15
16
  getCredentials : jest.fn(),
16
17
  validateCredentials : jest.fn(),
17
- createCredentials : jest.fn(),
18
+ createCredentials : jest.fn().mockImplementation(() => credentialsJSON),
18
19
  checkSecrets : jest.fn(),
19
20
  getScopesError : jest.fn().mockImplementation(() => scopesError),
20
21
  getSecretsError : jest.fn().mockImplementation(() => secretsError),
@@ -46,8 +47,9 @@ jest.mock('open', () => jest.fn().mockImplementation((url: string) => {
46
47
  }));
47
48
 
48
49
  jest.mock<Partial<typeof jsonLib>>('../jsonLib', () => ({
49
- getJSON : jest.fn().mockImplementation(() => json),
50
+ getJSON : jest.fn().mockImplementation(() => json),
50
51
  getJSONAsync : jest.fn().mockImplementation(async () => json),
52
+ readJSON : jest.fn().mockImplementation(async () => json),
51
53
  }));
52
54
 
53
55
  jest.mock<Partial<typeof logger>>('../logger', () => ({
@@ -57,6 +59,13 @@ jest.mock<Partial<typeof logger>>('../logger', () => ({
57
59
  }) as jest.Mock<never, any>,
58
60
  }));
59
61
 
62
+ jest.mock<Partial<typeof paths>>('../paths', () => ({
63
+ getScopesFile : jest.fn().mockImplementation(() => scopesFile),
64
+ getSecretsFile : jest.fn().mockImplementation(() => secretsFile),
65
+ getCredentialsFile : jest.fn().mockImplementation(() => credentialsFile),
66
+ ensureFile : jest.fn().mockImplementation(() => fileExists),
67
+ }));
68
+
60
69
  const profile = 'username1';
61
70
  const scopesFile = 'scopes.json';
62
71
  const secretsFile = 'secrets/username1.json';
@@ -85,11 +94,12 @@ const secretsJSON: Secrets = {
85
94
  },
86
95
  };
87
96
 
88
- const credentialsJSON = {
89
- token : {},
97
+ const credentialsJSON: GoogleApis.Auth.Credentials = {
98
+ // eslint-disable-next-line camelcase
99
+ access_token : 'access_token222',
90
100
  };
91
101
 
92
- let json: object;
102
+ let json: any;
93
103
 
94
104
  const code = 'code';
95
105
  const authUrl = 'https://authUrl';
@@ -138,6 +148,8 @@ const connections = [
138
148
  { remoteAddress : 'server', remotePort : '1003', on : jest.fn(), destroy : jest.fn() },
139
149
  ];
140
150
 
151
+ let fileExists: boolean;
152
+
141
153
  describe('src/lib/secrets', () => {
142
154
  describe('getScopes', () => {
143
155
  const getJSONSpy = jest.spyOn(jsonLib, 'getJSON');
@@ -203,7 +215,8 @@ describe('src/lib/secrets', () => {
203
215
  const getJSONAsyncSpy = jest.spyOn(jsonLib, 'getJSONAsync');
204
216
 
205
217
  beforeEach(() => {
206
- json = credentialsJSON;
218
+ json = credentialsJSON;
219
+ fileExists = false;
207
220
  });
208
221
 
209
222
  it('should get json from credentials file by default', async () => {
@@ -213,7 +226,7 @@ describe('src/lib/secrets', () => {
213
226
  expect(getJSONAsyncSpy.mock.calls[0][0]).toEqual(credentialsFile);
214
227
  });
215
228
 
216
- it('should get json from credentials file if temporariness explicitly unset', async () => {
229
+ it('should get json from credentials file if temporariness not set', async () => {
217
230
  await original.getCredentials(profile, auth, { temporary : false });
218
231
 
219
232
  expect(getJSONAsyncSpy).toBeCalled();
@@ -226,18 +239,22 @@ describe('src/lib/secrets', () => {
226
239
  expect(getJSONAsyncSpy).not.toBeCalled();
227
240
  });
228
241
 
229
- it('should fallback to createCredentials by default', async () => {
242
+ it('should call createCredentials in fallback', async () => {
230
243
  await original.getCredentials(profile, auth);
231
244
 
245
+ expect(secrets.createCredentials).not.toBeCalled();
246
+
232
247
  const fallback = getJSONAsyncSpy.mock.calls[0][1];
233
248
  await fallback();
234
249
 
235
250
  expect(secrets.createCredentials).toBeCalledWith(profile, auth, undefined);
236
251
  });
237
252
 
238
- it('should call createCredentials directly if temporariness explicitly unset', async () => {
253
+ it('should call createCredentials in fallback if temporariness not set', async () => {
239
254
  await original.getCredentials(profile, auth, { temporary : false });
240
255
 
256
+ expect(secrets.createCredentials).not.toBeCalled();
257
+
241
258
  const fallback = getJSONAsyncSpy.mock.calls[0][1];
242
259
  await fallback();
243
260
 
@@ -250,22 +267,60 @@ describe('src/lib/secrets', () => {
250
267
  expect(secrets.createCredentials).toBeCalledWith(profile, auth, { temporary : true });
251
268
  });
252
269
 
253
- it('should return credentials by default', async () => {
254
- const result = await original.getCredentials(profile, auth);
270
+ it('should return credentials in fallback', async () => {
271
+ await original.getCredentials(profile, auth);
272
+
273
+ const fallback = getJSONAsyncSpy.mock.calls[0][1];
274
+ const result = await fallback();
255
275
 
256
276
  expect(result).toEqual(credentialsJSON);
257
277
  });
258
278
 
259
- it('should return credentials if temporariness explicitly unset', async () => {
260
- const result = await original.getCredentials(profile, auth, { temporary : false });
279
+ it('should return credentials in fallback and copy existing refresh token from existing file if created credentials do not have refresh token', async () => {
280
+ fileExists = true;
281
+ // eslint-disable-next-line camelcase
282
+ jest.spyOn(jsonLib, 'readJSON').mockReturnValueOnce({ ...credentialsJSON, refresh_token : 'refresh_token' });
283
+
284
+ await original.getCredentials(profile, auth);
261
285
 
286
+ const fallback = getJSONAsyncSpy.mock.calls[0][1];
287
+ const result = await fallback();
288
+
289
+ expect(jsonLib.readJSON).toBeCalledWith(credentialsFile);
290
+ // eslint-disable-next-line camelcase
291
+ expect(result).toEqual({ ...credentialsJSON, refresh_token : 'refresh_token' });
292
+ });
293
+
294
+ it('should return credentials in fallback and leave refresh_token undefined if there is no existing file', async () => {
295
+ fileExists = false;
296
+ // eslint-disable-next-line camelcase
297
+ jest.spyOn(jsonLib, 'readJSON').mockReturnValueOnce({ ...credentialsJSON, refresh_token : 'refresh_token' });
298
+
299
+ await original.getCredentials(profile, auth);
300
+
301
+ const fallback = getJSONAsyncSpy.mock.calls[0][1];
302
+ const result = await fallback();
303
+
304
+ expect(jsonLib.readJSON).not.toBeCalled();
305
+ // eslint-disable-next-line camelcase
262
306
  expect(result).toEqual(credentialsJSON);
263
307
  });
264
308
 
265
- it('should return nothing if temporariness set', async () => {
266
- const result = await original.getCredentials(profile, auth, { temporary : true });
309
+ it('should return credentials in fallback and leave refresh_token as is if it is set from createCredentials', async () => {
310
+ fileExists = true;
311
+ // eslint-disable-next-line camelcase
312
+ jest.spyOn(secrets, 'createCredentials').mockResolvedValueOnce({ ...credentialsJSON, refresh_token : 'refresh_token_1' });
313
+ // eslint-disable-next-line camelcase
314
+ jest.spyOn(jsonLib, 'readJSON').mockReturnValueOnce({ ...credentialsJSON, refresh_token : 'refresh_token_2' });
315
+
316
+ await original.getCredentials(profile, auth);
317
+
318
+ const fallback = getJSONAsyncSpy.mock.calls[0][1];
319
+ const result = await fallback();
267
320
 
268
- expect(result).toBeUndefined();
321
+ expect(jsonLib.readJSON).toBeCalledWith(credentialsFile);
322
+ // eslint-disable-next-line camelcase
323
+ expect(result).toEqual({ ...credentialsJSON, refresh_token : 'refresh_token_1' });
269
324
  });
270
325
  });
271
326
 
@@ -274,23 +329,28 @@ describe('src/lib/secrets', () => {
274
329
  expect(await original.validateCredentials({})).toEqual(false);
275
330
  });
276
331
 
332
+ it('should return true if no refresh token', async () => {
333
+ // eslint-disable-next-line camelcase
334
+ expect(await original.validateCredentials({ access_token : 'token' })).toEqual(false);
335
+ });
336
+
277
337
  it('should return true if no expiration', async () => {
278
338
  // eslint-disable-next-line camelcase
279
- expect(await original.validateCredentials({ access_token : 'token' })).toEqual(true);
339
+ expect(await original.validateCredentials({ access_token : 'token', refresh_token : 'token' })).toEqual(true);
280
340
  });
281
341
 
282
342
  it('should return true if credentials are not more than 1 week ago', async () => {
283
343
  const expiryDate = new Date();
284
344
  expiryDate.setDate(expiryDate.getDate() - 6);
285
345
  // eslint-disable-next-line camelcase
286
- expect(await original.validateCredentials({ access_token : 'token', expiry_date : expiryDate.getTime() })).toEqual(true);
346
+ expect(await original.validateCredentials({ access_token : 'token', refresh_token : 'token', expiry_date : expiryDate.getTime() })).toEqual(true);
287
347
  });
288
348
 
289
349
  it('should return true if credentials are more than 1 week ago', async () => {
290
350
  const expiryDate = new Date();
291
351
  expiryDate.setDate(expiryDate.getDate() - 8);
292
352
  // eslint-disable-next-line camelcase
293
- expect(await original.validateCredentials({ access_token : 'token', expiry_date : expiryDate.getTime() })).toEqual(false);
353
+ expect(await original.validateCredentials({ access_token : 'token', refresh_token : 'token', expiry_date : expiryDate.getTime() })).toEqual(false);
294
354
  });
295
355
  });
296
356
 
@@ -302,6 +362,22 @@ describe('src/lib/secrets', () => {
302
362
 
303
363
  await original.createCredentials(profile, auth);
304
364
 
365
+ expect(auth.generateAuthUrl).toBeCalledWith({
366
+ // eslint-disable-next-line camelcase
367
+ access_type : 'offline',
368
+ prompt : 'consent',
369
+ scope : [
370
+ 'https://www.googleapis.com/auth/calendar.calendars.readonly',
371
+ 'https://www.googleapis.com/auth/calendar.events.readonly',
372
+ ],
373
+ });
374
+ });
375
+
376
+ it('should generate authUrl and do not require consent if credentials are temporary because refresh token is not required in credentials JSON', async () => {
377
+ willOpen(tokenUrl, 100);
378
+
379
+ await original.createCredentials(profile, auth, { temporary : true });
380
+
305
381
  expect(auth.generateAuthUrl).toBeCalledWith({
306
382
  // eslint-disable-next-line camelcase
307
383
  access_type : 'offline',
@@ -320,6 +396,7 @@ describe('src/lib/secrets', () => {
320
396
  expect(auth.generateAuthUrl).toBeCalledWith({
321
397
  // eslint-disable-next-line camelcase
322
398
  access_type : 'offline',
399
+ prompt : 'consent',
323
400
  scope : [ 'scope1', 'scope2' ],
324
401
  });
325
402
  });
@@ -4,7 +4,7 @@ import { ensureFile } from './paths';
4
4
 
5
5
  import jsonLib from './jsonLib';
6
6
 
7
- export { getJSON, getJSONAsync, writeJSON };
7
+ export { getJSON, getJSONAsync, writeJSON, readJSON };
8
8
  export default { getJSON, getJSONAsync, writeJSON, readJSON, checkJSON };
9
9
 
10
10
  function getJSON<T>(filename: string, createCallback: () => Exclude<T, Promise<any>>, validateJSON?: (json: T) => boolean): T {
@@ -3,9 +3,9 @@ import enableDestroy from 'server-destroy';
3
3
  import open from 'open';
4
4
  import type GoogleApis from 'googleapis';
5
5
  import type { Secrets, AuthOptions } from '../types';
6
- import { getJSON, getJSONAsync } from './jsonLib';
6
+ import { getJSON, getJSONAsync, readJSON } from './jsonLib';
7
7
  import { warn, error } from './logger';
8
- import { getScopesFile, getSecretsFile, getCredentialsFile } from './paths';
8
+ import { getScopesFile, getSecretsFile, getCredentialsFile, ensureFile } from './paths';
9
9
 
10
10
  import secrets from './secrets';
11
11
 
@@ -33,9 +33,17 @@ function getSecrets(profile: string): Secrets {
33
33
  async function getCredentials(profile: string, auth: GoogleApis.Common.OAuth2Client, options?: AuthOptions): Promise<GoogleApis.Auth.Credentials> {
34
34
  const credentialsFile = getCredentialsFile(profile);
35
35
 
36
- return options?.temporary
37
- ? secrets.createCredentials(profile, auth, options)
38
- : getJSONAsync(credentialsFile, () => secrets.createCredentials(profile, auth, options), secrets.validateCredentials);
36
+ if (options?.temporary) {
37
+ return secrets.createCredentials(profile, auth, options);
38
+ }
39
+
40
+ return getJSONAsync(credentialsFile, async () => {
41
+ // eslint-disable-next-line camelcase
42
+ const refresh_token = ensureFile(credentialsFile) ? readJSON<GoogleApis.Auth.Credentials>(credentialsFile).refresh_token : undefined;
43
+ const credentials = await secrets.createCredentials(profile, auth, options);
44
+ // eslint-disable-next-line camelcase
45
+ return { refresh_token, ...credentials };
46
+ }, secrets.validateCredentials);
39
47
  }
40
48
 
41
49
  async function validateCredentials(credentials: GoogleApis.Auth.Credentials): Promise<boolean> {
@@ -43,6 +51,10 @@ async function validateCredentials(credentials: GoogleApis.Auth.Credentials): Pr
43
51
  return false;
44
52
  }
45
53
 
54
+ if (!credentials.refresh_token) {
55
+ return false;
56
+ }
57
+
46
58
  if (!credentials.expiry_date) {
47
59
  return true;
48
60
  }
@@ -57,6 +69,7 @@ async function createCredentials(profile: string, auth: GoogleApis.Auth.OAuth2Cl
57
69
  const authUrl = auth.generateAuthUrl({
58
70
  // eslint-disable-next-line camelcase
59
71
  access_type : 'offline',
72
+ prompt : options?.temporary ? undefined : 'consent',
60
73
  scope,
61
74
  });
62
75