@flashbacktech/flashbackclient 0.0.73 → 0.0.74

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,5 +1,6 @@
1
1
  import { OAuth2Client } from 'google-auth-library';
2
2
  import { ServiceCredentials } from './storage';
3
+ import { GaxiosResponse } from 'gaxios';
3
4
  export declare class MockupAuthClient extends OAuth2Client {
4
5
  getRequestHeaders(): Promise<{
5
6
  Authorization: string;
@@ -7,13 +8,22 @@ export declare class MockupAuthClient extends OAuth2Client {
7
8
  }
8
9
  export declare class FlashbackAuthClient extends OAuth2Client {
9
10
  private authUrl;
11
+ private creds;
12
+ private _credentials;
10
13
  private scopes;
11
- private token;
12
- private tokenExpiry;
13
- private clientEmail;
14
- private privateKey;
15
14
  constructor(authUrl: string, scopes: string[], credentials: ServiceCredentials);
16
- private fetchToken;
17
- private ensureValidToken;
15
+ getCredentials(): Promise<{
16
+ client_email: string;
17
+ private_key: string;
18
+ }>;
19
+ getAccessToken(): Promise<{
20
+ token: string | null;
21
+ res: null;
22
+ }>;
18
23
  getRequestHeaders(): Promise<Record<string, string>>;
24
+ private ensureValidToken;
25
+ private fetchToken;
26
+ request<T = any>(opts: any): Promise<GaxiosResponse<T>>;
27
+ getRequestMetadata(url?: string): Promise<Record<string, string>>;
28
+ authorizeRequest(reqOpts: any): Promise<any>;
19
29
  }
@@ -18,31 +18,80 @@ class FlashbackAuthClient extends google_auth_library_1.OAuth2Client {
18
18
  constructor(authUrl, scopes, credentials) {
19
19
  super();
20
20
  this.authUrl = authUrl;
21
+ this._credentials = null;
22
+ this.creds = credentials;
21
23
  this.scopes = scopes;
22
- this.token = null;
23
- this.tokenExpiry = null;
24
- this.clientEmail = credentials.client_email;
25
- this.privateKey = credentials.private_key;
24
+ console.log('FlashbackAuthClient created with URL:', authUrl);
25
+ }
26
+ async getCredentials() {
27
+ return {
28
+ client_email: this.creds.client_email,
29
+ private_key: this.creds.private_key,
30
+ };
31
+ }
32
+ async getAccessToken() {
33
+ await this.ensureValidToken();
34
+ return {
35
+ token: this._credentials?.access_token || null,
36
+ res: null
37
+ };
38
+ }
39
+ async getRequestHeaders() {
40
+ await this.ensureValidToken();
41
+ return {
42
+ Authorization: `Bearer ${this._credentials?.access_token}`,
43
+ };
44
+ }
45
+ async ensureValidToken() {
46
+ const now = Date.now();
47
+ if (!this._credentials?.access_token || !this._credentials?.expiry_date || now >= this._credentials.expiry_date) {
48
+ await this.fetchToken();
49
+ }
26
50
  }
27
51
  async fetchToken() {
28
52
  const response = await axios_1.default.post(this.authUrl, {
29
- client_email: this.clientEmail,
30
- private_key: this.privateKey,
53
+ client_email: this.creds.client_email,
54
+ private_key: this.creds.private_key,
31
55
  scopes: this.scopes,
32
56
  });
33
57
  const { access_token, expires_in } = response.data;
34
- this.token = access_token;
35
- this.tokenExpiry = Date.now() + (expires_in * 1000) - 10000;
58
+ this._credentials = {
59
+ access_token,
60
+ expiry_date: Date.now() + (expires_in * 1000) - 10000,
61
+ };
36
62
  }
37
- async ensureValidToken() {
38
- if (!this.token || !this.tokenExpiry || Date.now() >= this.tokenExpiry) {
39
- await this.fetchToken();
40
- }
63
+ async request(opts) {
64
+ await this.ensureValidToken();
65
+ const headers = {
66
+ ...(opts.headers || {}),
67
+ Authorization: `Bearer ${this._credentials?.access_token}`,
68
+ };
69
+ const response = await axios_1.default.request({
70
+ ...opts,
71
+ headers,
72
+ });
73
+ return {
74
+ config: opts,
75
+ data: response.data,
76
+ headers: response.headers,
77
+ status: response.status,
78
+ statusText: response.statusText,
79
+ };
41
80
  }
42
- async getRequestHeaders() {
81
+ async getRequestMetadata(url) {
82
+ await this.ensureValidToken();
83
+ return {
84
+ Authorization: `Bearer ${this._credentials?.access_token}`,
85
+ };
86
+ }
87
+ async authorizeRequest(reqOpts) {
43
88
  await this.ensureValidToken();
44
89
  return {
45
- Authorization: `Bearer ${this.token}`,
90
+ ...reqOpts,
91
+ headers: {
92
+ ...(reqOpts.headers || {}),
93
+ Authorization: `Bearer ${this._credentials?.access_token}`,
94
+ },
46
95
  };
47
96
  }
48
97
  }
@@ -1,4 +1,4 @@
1
- import { Storage, StorageOptions } from '@google-cloud/storage';
1
+ import { Storage, StorageOptions, File } from '@google-cloud/storage';
2
2
  export interface ServiceCredentials {
3
3
  client_email: string;
4
4
  private_key: string;
@@ -8,6 +8,15 @@ export interface FlashbackStorageOptions extends Omit<StorageOptions, 'authClien
8
8
  tokenScopes?: string[];
9
9
  credentials: ServiceCredentials;
10
10
  }
11
+ export interface SignedUrlOptions {
12
+ version: 'v4';
13
+ action: 'write' | 'read';
14
+ expires: number;
15
+ contentType: string;
16
+ file: File;
17
+ }
11
18
  export declare class FlashbackGCSStorage extends Storage {
19
+ protected credentials: ServiceCredentials;
12
20
  constructor(opts: FlashbackStorageOptions);
21
+ getSignedUrl(cfg: SignedUrlOptions): Promise<[string]>;
13
22
  }
@@ -1,19 +1,103 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.FlashbackGCSStorage = void 0;
4
7
  const storage_1 = require("@google-cloud/storage");
5
8
  const oauth2_1 = require("./oauth2");
9
+ const crypto_1 = __importDefault(require("crypto"));
6
10
  class FlashbackGCSStorage extends storage_1.Storage {
7
11
  constructor(opts) {
8
12
  const { credentials, apiEndpoint = 'https://gcs.us-east-1.flashback.tech', tokenScopes = ['READ', 'WRITE'], ...rest } = opts;
9
- //const authClient = new FlashbackAuthClient(apiEndpoint + '/token', tokenScopes, credentials!);
10
- const authClient = new oauth2_1.MockupAuthClient();
13
+ const authClient = new oauth2_1.FlashbackAuthClient(apiEndpoint + '/token', tokenScopes, credentials);
14
+ // Intercept Gaxios instance creation
15
+ const originalRequest = require('gaxios').instance.request;
16
+ require('gaxios').instance.request = async function (opts) {
17
+ // Add auth headers to all requests
18
+ const headers = await authClient.getRequestHeaders();
19
+ opts.headers = {
20
+ ...(opts.headers || {}),
21
+ ...headers,
22
+ };
23
+ return originalRequest.call(this, opts);
24
+ };
11
25
  super({
12
26
  ...rest,
13
27
  apiEndpoint,
14
28
  authClient,
15
29
  useAuthWithCustomEndpoint: true,
30
+ retryOptions: {
31
+ autoRetry: true,
32
+ maxRetries: 3,
33
+ },
16
34
  });
35
+ this.credentials = credentials;
36
+ }
37
+ // Override the getSignedUrl method
38
+ async getSignedUrl(cfg) {
39
+ const { version, action, expires, contentType } = cfg;
40
+ const accessibleAt = new Date();
41
+ const millisecondsToSeconds = 1.0 / 1000.0;
42
+ const expiresPeriodInSeconds = Math.floor((expires - accessibleAt.valueOf()) * millisecondsToSeconds);
43
+ console.log('Signing Parameters:', {
44
+ action,
45
+ expires,
46
+ expiresPeriodInSeconds,
47
+ accessibleAt: accessibleAt.toISOString(),
48
+ contentType
49
+ });
50
+ if (expiresPeriodInSeconds > 604800) { // 7 days in seconds
51
+ throw new Error('Max allowed expiration is seven days (604800 seconds).');
52
+ }
53
+ const extensionHeaders = {};
54
+ extensionHeaders.host = new URL(this.apiEndpoint).hostname;
55
+ if (contentType) {
56
+ extensionHeaders['content-type'] = contentType;
57
+ }
58
+ const signedHeaders = Object.keys(extensionHeaders)
59
+ .map(header => header.toLowerCase())
60
+ .sort()
61
+ .join(';');
62
+ const canonicalHeaders = Object.entries(extensionHeaders)
63
+ .map(([key, value]) => `${key.toLowerCase()}:${value}`)
64
+ .join('\n') + '\n';
65
+ const datestamp = accessibleAt.toISOString().split('T')[0];
66
+ const credentialScope = `${datestamp}/auto/storage/goog4_request`;
67
+ const credential = `${this.credentials.client_email}/${credentialScope}`;
68
+ const dateISO = accessibleAt.toISOString().replace(/[:-]|\.\d{3}/g, '');
69
+ const queryParams = {
70
+ 'X-Goog-Algorithm': 'GOOG4-RSA-SHA256',
71
+ 'X-Goog-Credential': credential,
72
+ 'X-Goog-Date': dateISO,
73
+ 'X-Goog-Expires': expiresPeriodInSeconds.toString(),
74
+ 'X-Goog-SignedHeaders': signedHeaders,
75
+ };
76
+ const canonicalQueryString = Object.entries(queryParams)
77
+ .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
78
+ .join('&');
79
+ const canonicalRequest = [
80
+ action === 'read' ? 'GET' : 'PUT',
81
+ `/${cfg.file.bucket.name}/${cfg.file.name}`,
82
+ canonicalQueryString,
83
+ canonicalHeaders,
84
+ signedHeaders,
85
+ 'UNSIGNED-PAYLOAD',
86
+ ].join('\n');
87
+ console.log('Canonical Request:', canonicalRequest);
88
+ console.log('Canonical Request Hash:', crypto_1.default.createHash('sha256').update(canonicalRequest).digest('hex'));
89
+ const stringToSign = [
90
+ 'GOOG4-RSA-SHA256',
91
+ dateISO,
92
+ credentialScope,
93
+ crypto_1.default.createHash('sha256').update(canonicalRequest).digest('hex'),
94
+ ].join('\n');
95
+ console.log('String to Sign:', stringToSign);
96
+ const sign = crypto_1.default.createSign('RSA-SHA256');
97
+ sign.update(stringToSign);
98
+ const signature = sign.sign(this.credentials.private_key, 'hex');
99
+ console.log('Generated Signature:', signature);
100
+ return [`${this.apiEndpoint}/${cfg.file.bucket.name}/${cfg.file.name}?${canonicalQueryString}&X-Goog-Signature=${signature}`];
17
101
  }
18
102
  }
19
103
  exports.FlashbackGCSStorage = FlashbackGCSStorage;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flashbacktech/flashbackclient",
3
- "version": "0.0.73",
3
+ "version": "0.0.74",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },