Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/actions/airtable/airtable.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export declare class AirtableAction extends Hub.OAuthAction {
execute(request: Hub.ActionRequest): Promise<Hub.ActionResponse>;
checkBaseList(token: string): Promise<gaxios.GaxiosResponse<unknown>>;
form(request: Hub.ActionRequest): Promise<Hub.ActionForm>;
oauthCheck(_request: Hub.ActionRequest): Promise<boolean>;
oauthCheck(request: Hub.ActionRequest): Promise<boolean>;
oauthFetchInfo(urlParams: {
[p: string]: string;
}, redirectUri: string): Promise<void>;
Expand Down
76 changes: 41 additions & 35 deletions lib/actions/airtable/airtable.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const gaxios = require("gaxios");
const qs = require("qs");
const winston = require("winston");
const hub_1 = require("../../hub");
const airtable_tokens_1 = require("./airtable_tokens");
const airtable = require("airtable");
class AirtableAction extends Hub.OAuthAction {
constructor() {
Expand Down Expand Up @@ -49,32 +50,26 @@ class AirtableAction extends Hub.OAuthAction {
const state = new hub_1.ActionState();
try {
let accessToken;
let tokens;
if (request.params.state_json) {
const stateJson = JSON.parse(request.params.state_json);
accessToken = stateJson.tokens.access_token;
state.data = JSON.stringify({
tokens: {
refresh_token: stateJson.tokens.refresh_token,
access_token: accessToken,
},
});
const stateJson = await this.oauthExtractTokensFromStateJson(request.params.state_json, request.webhookId);
tokens = airtable_tokens_1.AirtableTokens.fromJson(stateJson);
accessToken = tokens.access_token;
const encrypted = await this.oauthMaybeEncryptTokens(new airtable_tokens_1.AirtableTokens(tokens.refresh_token, accessToken, tokens.redirectUri), request.webhookId);
state.data = typeof encrypted === "string" ? encrypted : JSON.stringify(encrypted);
}
try {
await this.executeAirtable(request, records, accessToken);
}
catch (_a) {
if (request.params.state_json) {
const stateJson = JSON.parse(request.params.state_json);
if (request.params.state_json && tokens) {
const stateJson = await this.oauthExtractTokensFromStateJson(request.params.state_json, request.webhookId);
const refreshResponse = await this.refreshTokens(stateJson.tokens.refresh_token);
// @ts-ignore
if (Object.keys(refreshResponse.data).length !== 0) {
accessToken = refreshResponse.data.access_token;
state.data = JSON.stringify({
tokens: {
refresh_token: refreshResponse.data.refresh_token,
access_token: accessToken,
},
});
const refreshData = refreshResponse.data;
if (Object.keys(refreshData).length !== 0) {
accessToken = refreshData.access_token;
const encrypted = await this.oauthMaybeEncryptTokens(new airtable_tokens_1.AirtableTokens(refreshData.refresh_token, accessToken, tokens.redirectUri), request.webhookId);
state.data = typeof encrypted === "string" ? encrypted : JSON.stringify(encrypted);
}
else {
delete state.data;
Expand Down Expand Up @@ -106,30 +101,36 @@ class AirtableAction extends Hub.OAuthAction {
const form = new Hub.ActionForm();
try {
let accessToken;
let tokens;
if (request.params.state_json) {
const stateJson = JSON.parse(request.params.state_json);
accessToken = stateJson.tokens.access_token;
const stateJson = await this.oauthExtractTokensFromStateJson(request.params.state_json, request.webhookId);
tokens = airtable_tokens_1.AirtableTokens.fromJson(stateJson);
accessToken = tokens.access_token;
}
try {
await this.checkBaseList(accessToken);
if (form.state === undefined) {
form.state = new hub_1.ActionState();
form.state.data = request.params.state_json;
if (tokens) {
const encrypted = await this.oauthMaybeEncryptTokens(tokens, request.webhookId);
const encryptedStr = typeof encrypted === "string" ? encrypted : JSON.stringify(encrypted);
request.params.state_json = encryptedStr;
form.state.data = encryptedStr;
}
}
}
catch (_a) {
// Assume the failure is due to Oauth failure,
// refresh token and retry once.
if (request.params.state_json) {
const stateJson = JSON.parse(request.params.state_json);
if (request.params.state_json && tokens) {
const stateJson = await this.oauthExtractTokensFromStateJson(request.params.state_json, request.webhookId);
const refreshResponse = await this.refreshTokens(stateJson.tokens.refresh_token);
if (Object.keys(refreshResponse.data).length !== 0) {
accessToken = refreshResponse.data.access_token;
const refreshData = refreshResponse.data;
if (Object.keys(refreshData).length !== 0) {
accessToken = refreshData.access_token;
form.state = new hub_1.ActionState();
form.state.data = JSON.stringify({ tokens: {
refresh_token: refreshResponse.data.refresh_token,
access_token: accessToken,
} });
const encrypted = await this.oauthMaybeEncryptTokens(new airtable_tokens_1.AirtableTokens(refreshData.refresh_token, accessToken, tokens.redirectUri), request.webhookId);
form.state.data = typeof encrypted === "string" ? encrypted : JSON.stringify(encrypted);
}
}
await this.checkBaseList(accessToken);
Expand Down Expand Up @@ -164,7 +165,13 @@ class AirtableAction extends Hub.OAuthAction {
}
return form;
}
async oauthCheck(_request) {
async oauthCheck(request) {
if (request.params.state_json) {
const stateJson = await this.oauthExtractTokensFromStateJson(request.params.state_json, request.webhookId);
if (stateJson) {
return true;
}
}
return false;
}
async oauthFetchInfo(urlParams, redirectUri) {
Expand Down Expand Up @@ -195,13 +202,12 @@ class AirtableAction extends Hub.OAuthAction {
// Pass back context to Looker
if (response.status === 200) {
const data = response.data;
const tokenPayload = new airtable_tokens_1.AirtableTokens(data.refresh_token, data.access_token, redirectUri);
const encrypted = await this.oauthMaybeEncryptTokens(tokenPayload, undefined);
await gaxios.request({
url: payload.stateurl,
method: "POST",
body: JSON.stringify({ tokens: {
refresh_token: data.refresh_token,
access_token: data.access_token,
}, redirect: redirectUri }),
body: encrypted,
}).catch((_err) => { winston.error(_err.toString()); });
}
else {
Expand Down
10 changes: 10 additions & 0 deletions lib/actions/airtable/airtable_tokens.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { TokenPayload } from "../../hub";
export declare class AirtableTokens extends TokenPayload {
static fromJson(json: any): AirtableTokens;
refresh_token: string;
access_token: string;
redirectUri?: string;
constructor(refreshToken: string, accessToken: string, redirectUri?: string);
asJson(): any;
toJSON(): any;
}
31 changes: 31 additions & 0 deletions lib/actions/airtable/airtable_tokens.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AirtableTokens = void 0;
const hub_1 = require("../../hub");
class AirtableTokens extends hub_1.TokenPayload {
static fromJson(json) {
if (json.tokens) {
return new AirtableTokens(json.tokens.refresh_token, json.tokens.access_token, json.redirect);
}
return new AirtableTokens(json.refresh_token, json.access_token, json.redirectUri);
}
constructor(refreshToken, accessToken, redirectUri) {
super();
this.refresh_token = refreshToken;
this.access_token = accessToken;
this.redirectUri = redirectUri;
}
asJson() {
return {
tokens: {
refresh_token: this.refresh_token,
access_token: this.access_token,
},
redirect: this.redirectUri,
};
}
toJSON() {
return this.asJson();
}
}
exports.AirtableTokens = AirtableTokens;
2 changes: 1 addition & 1 deletion lib/actions/dropbox/dropbox.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ export declare class DropboxAction extends Hub.OAuthAction {
oauthCheck(request: Hub.ActionRequest): Promise<boolean>;
dropboxFilename(request: Hub.ActionRequest): string | undefined;
protected getAccessTokenFromCode(stateJson: any): Promise<any>;
protected dropboxClientFromRequest(request: Hub.ActionRequest, token: string): Dropbox;
protected dropboxClientFromRequest(request: Hub.ActionRequest, token: string): Promise<Dropbox>;
}
18 changes: 9 additions & 9 deletions lib/actions/dropbox/dropbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ class DropboxAction extends Hub.OAuthAction {
const ext = request.attachment.fileExtension;
let accessToken = "";
if (request.params.state_json) {
const stateJson = JSON.parse(request.params.state_json);
const stateJson = await this.oauthExtractTokensFromStateJson(request.params.state_json, request.webhookId);
if (stateJson.code && stateJson.redirect) {
accessToken = await this.getAccessTokenFromCode(stateJson);
}
}
const drop = this.dropboxClientFromRequest(request, accessToken);
const drop = await this.dropboxClientFromRequest(request, accessToken);
const resp = new Hub.ActionResponse();
resp.success = true;
if (request.attachment && request.attachment.dataBuffer) {
Expand All @@ -56,7 +56,7 @@ class DropboxAction extends Hub.OAuthAction {
let accessToken = "";
if (request.params.state_json) {
try {
const stateJson = JSON.parse(request.params.state_json);
const stateJson = await this.oauthExtractTokensFromStateJson(request.params.state_json, request.webhookId);
if (stateJson.code && stateJson.redirect) {
accessToken = await this.getAccessTokenFromCode(stateJson);
}
Expand All @@ -65,7 +65,7 @@ class DropboxAction extends Hub.OAuthAction {
winston.warn("Could not parse state_json");
}
}
const drop = this.dropboxClientFromRequest(request, accessToken);
const drop = await this.dropboxClientFromRequest(request, accessToken);
try {
const response = await drop.filesListFolder({ path: "" });
const folderList = response.entries.filter((entries) => (entries[".tag"] === "folder"))
Expand Down Expand Up @@ -100,9 +100,9 @@ class DropboxAction extends Hub.OAuthAction {
}],
}];
if (accessToken !== "") {
const newState = JSON.stringify({ access_token: accessToken });
const encrypted = await this.oauthMaybeEncryptTokens({ access_token: accessToken }, request.webhookId);
form.state = new Hub.ActionState();
form.state.data = newState;
form.state.data = typeof encrypted === "string" ? encrypted : JSON.stringify(encrypted);
}
Comment thread
jeffrey-martinez marked this conversation as resolved.
return form;
}
Expand Down Expand Up @@ -149,7 +149,7 @@ class DropboxAction extends Hub.OAuthAction {
}).catch((_err) => { winston.error(_err.toString()); });
}
async oauthCheck(request) {
const drop = this.dropboxClientFromRequest(request, "");
const drop = await this.dropboxClientFromRequest(request, "");
try {
await drop.filesListFolder({ path: "" });
return true;
Expand Down Expand Up @@ -185,10 +185,10 @@ class DropboxAction extends Hub.OAuthAction {
.catch((_err) => { winston.error("Error requesting access_token"); });
return response.access_token;
}
dropboxClientFromRequest(request, token) {
async dropboxClientFromRequest(request, token) {
if (request.params.state_json && token === "") {
try {
const json = JSON.parse(request.params.state_json);
const json = await this.oauthExtractTokensFromStateJson(request.params.state_json, request.webhookId);
token = json.access_token;
}
catch (er) {
Expand Down
7 changes: 4 additions & 3 deletions lib/actions/facebook/facebook_custom_audiences.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,11 @@ class FacebookCustomAudiencesAction extends Hub.OAuthAction {
const userState = { tokens, redirect: redirectUri };
// So now we use that state url to persist the oauth tokens
try {
const encrypted = await this.oauthMaybeEncryptTokens(userState, payload.webhookId);
await gaxios.request({
method: "POST",
url: payload.stateUrl,
data: userState,
data: typeof encrypted === "string" ? encrypted : encrypted,
});
}
catch (err) {
Expand Down Expand Up @@ -151,8 +152,8 @@ class FacebookCustomAudiencesAction extends Hub.OAuthAction {
}
async getAccessTokenFromRequest(request) {
try {
const params = request.params;
return JSON.parse(params.state_json).tokens.longLivedToken;
const stateJson = await this.oauthExtractTokensFromStateJson(`${request.params.state_json}`, request.webhookId);
return stateJson.tokens.longLivedToken;
}
catch (e) {
winston.error(`${LOG_PREFIX} Failed to parse state for access token.`, { webhookId: request.webhookId });
Expand Down
6 changes: 4 additions & 2 deletions lib/actions/google/ads/customer_match.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ class GoogleAdsCustomerMatch extends Hub.OAuthAction {
const adsRequest = await ads_request_1.GoogleAdsActionRequest.fromHub(hubReq, this, log);
await adsRequest.execute();
log("info", "Execution complete");
return wrappedResp.returnSuccess(adsRequest.userState);
const encrypted = await this.oauthMaybeEncryptTokens(adsRequest.userState, hubReq.webhookId);
return wrappedResp.returnSuccess(encrypted);
}
catch (err) {
(0, error_utils_1.sanitizeError)(err);
Expand All @@ -79,7 +80,8 @@ class GoogleAdsCustomerMatch extends Hub.OAuthAction {
try {
const adsWorker = await ads_request_1.GoogleAdsActionRequest.fromHub(hubReq, this, log);
wrappedResp.form = await adsWorker.makeForm();
return wrappedResp.returnSuccess(adsWorker.userState);
const encrypted = await this.oauthMaybeEncryptTokens(adsWorker.userState, hubReq.webhookId);
return wrappedResp.returnSuccess(encrypted);
// Use this code if you need to force a state reset and redo oauth login
// wrappedResp.form = await this.oauthHelper.makeLoginForm(hubReq)
// wrappedResp.resetState()
Expand Down
2 changes: 1 addition & 1 deletion lib/actions/google/ads/lib/ads_request.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export declare class GoogleAdsActionRequest {
formParams: any;
userState: AdsUserState;
webhookId?: string;
constructor(hubRequest: Hub.ActionRequest, actionInstance: GoogleAdsCustomerMatch, log: Logger);
constructor(hubRequest: Hub.ActionRequest, actionInstance: GoogleAdsCustomerMatch, log: Logger, userState: any);
checkTokens(): Promise<void>;
setApiClient(): void;
get accessToken(): string;
Expand Down
8 changes: 4 additions & 4 deletions lib/actions/google/ads/lib/ads_request.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,24 @@ exports.GoogleAdsActionRequest = void 0;
const winston = require("winston");
const missing_auth_error_1 = require("../../common/missing_auth_error");
const missing_required_params_error_1 = require("../../common/missing_required_params_error");
const utils_1 = require("../../common/utils");
const ads_executor_1 = require("./ads_executor");
const ads_form_builder_1 = require("./ads_form_builder");
const api_client_1 = require("./api_client");
const LOG_PREFIX = "[G Ads Customer Match]";
class GoogleAdsActionRequest {
static async fromHub(hubRequest, action, logger) {
const adsReq = new GoogleAdsActionRequest(hubRequest, action, logger);
const userState = await action.oauthExtractTokensFromStateJson(`${hubRequest.params.state_json}`, hubRequest.webhookId);
const adsReq = new GoogleAdsActionRequest(hubRequest, action, logger, userState);
await adsReq.checkTokens();
adsReq.setApiClient();
return adsReq;
}
constructor(hubRequest, actionInstance, log) {
constructor(hubRequest, actionInstance, log, userState) {
this.hubRequest = hubRequest;
this.actionInstance = actionInstance;
this.log = log;
this.streamingDownload = this.hubRequest.stream.bind(this.hubRequest);
const state = (0, utils_1.safeParseJson)(`${hubRequest.params.state_json}`);
const state = userState;
if (!state || !state.tokens || !state.tokens.access_token || !state.tokens.refresh_token || !state.redirect) {
winston.warn(`${LOG_PREFIX} User state was missing or did not contain oauth tokens & redirect`, { webhookId: hubRequest.webhookId });
throw new missing_auth_error_1.MissingAuthError("User state was missing or did not contain oauth tokens & redirect");
Expand Down
3 changes: 2 additions & 1 deletion lib/actions/google/analytics/data_import.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ class GoogleAnalyticsDataImportAction extends Hub.OAuthAction {
log("debug", "New upload id=", gaWorker.newUploadId);
// Since the upload was successful, update the lastUsedFormParams in user state
gaWorker.setLastUsedFormParams();
wrappedResp.setUserState(gaWorker.userState);
const encrypted = await this.oauthMaybeEncryptTokens(gaWorker.userState, hubReq.webhookId);
wrappedResp.setUserState(encrypted);
if (gaWorker.isDeleteOtherFiles) {
currentStep = "Delete other files step";
await gaWorker.deleteOtherFiles();
Expand Down
2 changes: 1 addition & 1 deletion lib/actions/google/analytics/lib/ga_worker.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export declare class GoogleAnalyticsActionWorker {
userState: GAUserState;
formParams: any;
newUploadId?: string;
constructor(hubRequest: Hub.ActionRequest, actionInstance: GoogleAnalyticsDataImportAction, log: Logger);
constructor(hubRequest: Hub.ActionRequest, actionInstance: GoogleAnalyticsDataImportAction, log: Logger, userState: any);
makeGAClient(): analytics_v3.Analytics;
get redirect(): string;
get tokens(): Credentials;
Expand Down
Loading
Loading