mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
refactor(core): Google service account remove duplicated functions (no-changelog) (#6368)
This commit is contained in:
@@ -8,64 +8,12 @@ import type {
|
|||||||
JsonObject,
|
JsonObject,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import { NodeApiError, NodeOperationError } from 'n8n-workflow';
|
import { NodeApiError, NodeOperationError } from 'n8n-workflow';
|
||||||
|
import { getGoogleAccessToken } from '../../GenericFunctions';
|
||||||
import moment from 'moment-timezone';
|
|
||||||
|
|
||||||
import * as jwt from 'jsonwebtoken';
|
|
||||||
|
|
||||||
async function getAccessToken(
|
|
||||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
|
||||||
credentials: IDataObject,
|
|
||||||
): Promise<IDataObject> {
|
|
||||||
//https://developers.google.com/identity/protocols/oauth2/service-account#httprest
|
|
||||||
|
|
||||||
const privateKey = (credentials.privateKey as string).replace(/\\n/g, '\n').trim();
|
|
||||||
|
|
||||||
const scopes = ['https://www.googleapis.com/auth/bigquery'];
|
|
||||||
|
|
||||||
const now = moment().unix();
|
|
||||||
|
|
||||||
const signature = jwt.sign(
|
|
||||||
{
|
|
||||||
iss: credentials.email as string,
|
|
||||||
sub: credentials.delegatedEmail || (credentials.email as string),
|
|
||||||
scope: scopes.join(' '),
|
|
||||||
aud: 'https://oauth2.googleapis.com/token',
|
|
||||||
iat: now,
|
|
||||||
exp: now + 3600,
|
|
||||||
},
|
|
||||||
privateKey,
|
|
||||||
{
|
|
||||||
algorithm: 'RS256',
|
|
||||||
header: {
|
|
||||||
kid: privateKey,
|
|
||||||
typ: 'JWT',
|
|
||||||
alg: 'RS256',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const options: OptionsWithUri = {
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
},
|
|
||||||
method: 'POST',
|
|
||||||
form: {
|
|
||||||
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
|
||||||
assertion: signature,
|
|
||||||
},
|
|
||||||
uri: 'https://oauth2.googleapis.com/token',
|
|
||||||
json: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
return this.helpers.request(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function googleApiRequest(
|
export async function googleApiRequest(
|
||||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
||||||
method: string,
|
method: string,
|
||||||
resource: string,
|
resource: string,
|
||||||
|
|
||||||
body: any = {},
|
body: any = {},
|
||||||
qs: IDataObject = {},
|
qs: IDataObject = {},
|
||||||
uri?: string,
|
uri?: string,
|
||||||
@@ -102,7 +50,7 @@ export async function googleApiRequest(
|
|||||||
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const { access_token } = await getAccessToken.call(this, credentials as IDataObject);
|
const { access_token } = await getGoogleAccessToken.call(this, credentials, 'bigquery');
|
||||||
|
|
||||||
options.headers!.Authorization = `Bearer ${access_token}`;
|
options.headers!.Authorization = `Bearer ${access_token}`;
|
||||||
return await this.helpers.request(options);
|
return await this.helpers.request(options);
|
||||||
|
|||||||
@@ -1,58 +1,9 @@
|
|||||||
import type { OptionsWithUri } from 'request';
|
import type { OptionsWithUri } from 'request';
|
||||||
import moment from 'moment-timezone';
|
|
||||||
import * as jwt from 'jsonwebtoken';
|
|
||||||
|
|
||||||
import type { IExecuteFunctions, IExecuteSingleFunctions, ILoadOptionsFunctions } from 'n8n-core';
|
import type { IExecuteFunctions, IExecuteSingleFunctions, ILoadOptionsFunctions } from 'n8n-core';
|
||||||
import type { IDataObject, JsonObject } from 'n8n-workflow';
|
import type { IDataObject, JsonObject } from 'n8n-workflow';
|
||||||
import { NodeApiError, NodeOperationError } from 'n8n-workflow';
|
import { NodeApiError, NodeOperationError } from 'n8n-workflow';
|
||||||
|
import { getGoogleAccessToken } from '../../../GenericFunctions';
|
||||||
async function getAccessToken(
|
|
||||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
|
||||||
credentials: IDataObject,
|
|
||||||
): Promise<IDataObject> {
|
|
||||||
//https://developers.google.com/identity/protocols/oauth2/service-account#httprest
|
|
||||||
|
|
||||||
const privateKey = (credentials.privateKey as string).replace(/\\n/g, '\n').trim();
|
|
||||||
|
|
||||||
const scopes = ['https://www.googleapis.com/auth/bigquery'];
|
|
||||||
|
|
||||||
const now = moment().unix();
|
|
||||||
|
|
||||||
const signature = jwt.sign(
|
|
||||||
{
|
|
||||||
iss: credentials.email as string,
|
|
||||||
sub: credentials.delegatedEmail || (credentials.email as string),
|
|
||||||
scope: scopes.join(' '),
|
|
||||||
aud: 'https://oauth2.googleapis.com/token',
|
|
||||||
iat: now,
|
|
||||||
exp: now + 3600,
|
|
||||||
},
|
|
||||||
privateKey,
|
|
||||||
{
|
|
||||||
algorithm: 'RS256',
|
|
||||||
header: {
|
|
||||||
kid: privateKey,
|
|
||||||
typ: 'JWT',
|
|
||||||
alg: 'RS256',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const options: OptionsWithUri = {
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
},
|
|
||||||
method: 'POST',
|
|
||||||
form: {
|
|
||||||
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
|
||||||
assertion: signature,
|
|
||||||
},
|
|
||||||
uri: 'https://oauth2.googleapis.com/token',
|
|
||||||
json: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
return this.helpers.request(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function googleApiRequest(
|
export async function googleApiRequest(
|
||||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
||||||
@@ -94,7 +45,7 @@ export async function googleApiRequest(
|
|||||||
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
throw new NodeOperationError(this.getNode(), 'No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const { access_token } = await getAccessToken.call(this, credentials as IDataObject);
|
const { access_token } = await getGoogleAccessToken.call(this, credentials, 'bigquery');
|
||||||
|
|
||||||
options.headers!.Authorization = `Bearer ${access_token}`;
|
options.headers!.Authorization = `Bearer ${access_token}`;
|
||||||
return await this.helpers.request(options);
|
return await this.helpers.request(options);
|
||||||
|
|||||||
@@ -8,72 +8,12 @@ import type {
|
|||||||
JsonObject,
|
JsonObject,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import { NodeApiError } from 'n8n-workflow';
|
import { NodeApiError } from 'n8n-workflow';
|
||||||
|
import { getGoogleAccessToken } from '../GenericFunctions';
|
||||||
import moment from 'moment-timezone';
|
|
||||||
|
|
||||||
import jwt from 'jsonwebtoken';
|
|
||||||
|
|
||||||
interface IGoogleAuthCredentials {
|
|
||||||
delegatedEmail?: string;
|
|
||||||
email: string;
|
|
||||||
inpersonate: boolean;
|
|
||||||
privateKey: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getAccessToken(
|
|
||||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
|
||||||
credentials: IGoogleAuthCredentials,
|
|
||||||
): Promise<IDataObject> {
|
|
||||||
//https://developers.google.com/identity/protocols/oauth2/service-account#httprest
|
|
||||||
|
|
||||||
const scopes = ['https://www.googleapis.com/auth/books'];
|
|
||||||
|
|
||||||
const now = moment().unix();
|
|
||||||
|
|
||||||
credentials.email = credentials.email.trim();
|
|
||||||
const privateKey = credentials.privateKey.replace(/\\n/g, '\n').trim();
|
|
||||||
|
|
||||||
const signature = jwt.sign(
|
|
||||||
{
|
|
||||||
iss: credentials.email,
|
|
||||||
sub: credentials.delegatedEmail || credentials.email,
|
|
||||||
scope: scopes.join(' '),
|
|
||||||
aud: 'https://oauth2.googleapis.com/token',
|
|
||||||
iat: now,
|
|
||||||
exp: now + 3600,
|
|
||||||
},
|
|
||||||
privateKey,
|
|
||||||
{
|
|
||||||
algorithm: 'RS256',
|
|
||||||
header: {
|
|
||||||
kid: privateKey,
|
|
||||||
typ: 'JWT',
|
|
||||||
alg: 'RS256',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const options: OptionsWithUri = {
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
},
|
|
||||||
method: 'POST',
|
|
||||||
form: {
|
|
||||||
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
|
||||||
assertion: signature,
|
|
||||||
},
|
|
||||||
uri: 'https://oauth2.googleapis.com/token',
|
|
||||||
json: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
return this.helpers.request(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function googleApiRequest(
|
export async function googleApiRequest(
|
||||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
||||||
method: string,
|
method: string,
|
||||||
resource: string,
|
resource: string,
|
||||||
|
|
||||||
body: any = {},
|
body: any = {},
|
||||||
qs: IDataObject = {},
|
qs: IDataObject = {},
|
||||||
uri?: string,
|
uri?: string,
|
||||||
@@ -108,10 +48,7 @@ export async function googleApiRequest(
|
|||||||
privateKey: string;
|
privateKey: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const { access_token } = await getAccessToken.call(
|
const { access_token } = await getGoogleAccessToken.call(this, credentials, 'books');
|
||||||
this,
|
|
||||||
credentials as unknown as IGoogleAuthCredentials,
|
|
||||||
);
|
|
||||||
|
|
||||||
options.headers!.Authorization = `Bearer ${access_token}`;
|
options.headers!.Authorization = `Bearer ${access_token}`;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import type { OptionsWithUri } from 'request';
|
import type { OptionsWithUri } from 'request';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ICredentialTestFunctions,
|
|
||||||
IDataObject,
|
IDataObject,
|
||||||
IExecuteFunctions,
|
IExecuteFunctions,
|
||||||
IExecuteSingleFunctions,
|
IExecuteSingleFunctions,
|
||||||
@@ -11,69 +10,7 @@ import type {
|
|||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import { NodeApiError } from 'n8n-workflow';
|
import { NodeApiError } from 'n8n-workflow';
|
||||||
|
|
||||||
import moment from 'moment-timezone';
|
import { getGoogleAccessToken } from '../GenericFunctions';
|
||||||
|
|
||||||
import jwt from 'jsonwebtoken';
|
|
||||||
|
|
||||||
interface IGoogleAuthCredentials {
|
|
||||||
delegatedEmail?: string;
|
|
||||||
email: string;
|
|
||||||
inpersonate: boolean;
|
|
||||||
privateKey: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getAccessToken(
|
|
||||||
this:
|
|
||||||
| IExecuteFunctions
|
|
||||||
| IExecuteSingleFunctions
|
|
||||||
| ILoadOptionsFunctions
|
|
||||||
| ICredentialTestFunctions,
|
|
||||||
credentials: IGoogleAuthCredentials,
|
|
||||||
): Promise<IDataObject> {
|
|
||||||
//https://developers.google.com/identity/protocols/oauth2/service-account#httprest
|
|
||||||
|
|
||||||
const scopes = ['https://www.googleapis.com/auth/chat.bot'];
|
|
||||||
|
|
||||||
const now = moment().unix();
|
|
||||||
|
|
||||||
credentials.email = credentials.email.trim();
|
|
||||||
const privateKey = credentials.privateKey.replace(/\\n/g, '\n').trim();
|
|
||||||
|
|
||||||
const signature = jwt.sign(
|
|
||||||
{
|
|
||||||
iss: credentials.email,
|
|
||||||
sub: credentials.delegatedEmail || credentials.email,
|
|
||||||
scope: scopes.join(' '),
|
|
||||||
aud: 'https://oauth2.googleapis.com/token',
|
|
||||||
iat: now,
|
|
||||||
exp: now + 3600,
|
|
||||||
},
|
|
||||||
privateKey,
|
|
||||||
{
|
|
||||||
algorithm: 'RS256',
|
|
||||||
header: {
|
|
||||||
kid: privateKey,
|
|
||||||
typ: 'JWT',
|
|
||||||
alg: 'RS256',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const options: OptionsWithUri = {
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
},
|
|
||||||
method: 'POST',
|
|
||||||
form: {
|
|
||||||
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
|
||||||
assertion: signature,
|
|
||||||
},
|
|
||||||
uri: 'https://oauth2.googleapis.com/token',
|
|
||||||
json: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
return this.helpers.request(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function googleApiRequest(
|
export async function googleApiRequest(
|
||||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
||||||
@@ -112,10 +49,7 @@ export async function googleApiRequest(
|
|||||||
} else {
|
} else {
|
||||||
const credentials = await this.getCredentials('googleApi');
|
const credentials = await this.getCredentials('googleApi');
|
||||||
|
|
||||||
const { access_token } = await getAccessToken.call(
|
const { access_token } = await getGoogleAccessToken.call(this, credentials, 'chat');
|
||||||
this,
|
|
||||||
credentials as unknown as IGoogleAuthCredentials,
|
|
||||||
);
|
|
||||||
options.headers!.Authorization = `Bearer ${access_token}`;
|
options.headers!.Authorization = `Bearer ${access_token}`;
|
||||||
responseData = await this.helpers.request(options);
|
responseData = await this.helpers.request(options);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,69 +8,7 @@ import type {
|
|||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import { NodeApiError } from 'n8n-workflow';
|
import { NodeApiError } from 'n8n-workflow';
|
||||||
|
|
||||||
import moment from 'moment-timezone';
|
import { getGoogleAccessToken } from '../GenericFunctions';
|
||||||
|
|
||||||
import jwt from 'jsonwebtoken';
|
|
||||||
|
|
||||||
interface IGoogleAuthCredentials {
|
|
||||||
delegatedEmail?: string;
|
|
||||||
email: string;
|
|
||||||
inpersonate: boolean;
|
|
||||||
privateKey: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getAccessToken(
|
|
||||||
this: IExecuteFunctions | ILoadOptionsFunctions,
|
|
||||||
credentials: IGoogleAuthCredentials,
|
|
||||||
): Promise<IDataObject> {
|
|
||||||
//https://developers.google.com/identity/protocols/oauth2/service-account#httprest
|
|
||||||
|
|
||||||
const scopes = [
|
|
||||||
'https://www.googleapis.com/auth/documents',
|
|
||||||
'https://www.googleapis.com/auth/drive',
|
|
||||||
'https://www.googleapis.com/auth/drive.file',
|
|
||||||
];
|
|
||||||
|
|
||||||
const now = moment().unix();
|
|
||||||
|
|
||||||
credentials.email = credentials.email.trim();
|
|
||||||
const privateKey = credentials.privateKey.replace(/\\n/g, '\n').trim();
|
|
||||||
|
|
||||||
const signature = jwt.sign(
|
|
||||||
{
|
|
||||||
iss: credentials.email,
|
|
||||||
sub: credentials.delegatedEmail || credentials.email,
|
|
||||||
scope: scopes.join(' '),
|
|
||||||
aud: 'https://oauth2.googleapis.com/token',
|
|
||||||
iat: now,
|
|
||||||
exp: now + 3600,
|
|
||||||
},
|
|
||||||
privateKey,
|
|
||||||
{
|
|
||||||
algorithm: 'RS256',
|
|
||||||
header: {
|
|
||||||
kid: privateKey,
|
|
||||||
typ: 'JWT',
|
|
||||||
alg: 'RS256',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const options: OptionsWithUri = {
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
},
|
|
||||||
method: 'POST',
|
|
||||||
form: {
|
|
||||||
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
|
||||||
assertion: signature,
|
|
||||||
},
|
|
||||||
uri: 'https://oauth2.googleapis.com/token',
|
|
||||||
json: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
return this.helpers.request(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function googleApiRequest(
|
export async function googleApiRequest(
|
||||||
this: IExecuteFunctions | ILoadOptionsFunctions,
|
this: IExecuteFunctions | ILoadOptionsFunctions,
|
||||||
@@ -104,10 +42,7 @@ export async function googleApiRequest(
|
|||||||
if (authenticationMethod === 'serviceAccount') {
|
if (authenticationMethod === 'serviceAccount') {
|
||||||
const credentials = await this.getCredentials('googleApi');
|
const credentials = await this.getCredentials('googleApi');
|
||||||
|
|
||||||
const { access_token } = await getAccessToken.call(
|
const { access_token } = await getGoogleAccessToken.call(this, credentials, 'docs');
|
||||||
this,
|
|
||||||
credentials as unknown as IGoogleAuthCredentials,
|
|
||||||
);
|
|
||||||
|
|
||||||
options.headers!.Authorization = `Bearer ${access_token}`;
|
options.headers!.Authorization = `Bearer ${access_token}`;
|
||||||
return await this.helpers.request(options);
|
return await this.helpers.request(options);
|
||||||
|
|||||||
@@ -10,75 +10,12 @@ import type {
|
|||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import { NodeApiError } from 'n8n-workflow';
|
import { NodeApiError } from 'n8n-workflow';
|
||||||
|
|
||||||
import moment from 'moment-timezone';
|
import { getGoogleAccessToken } from '../GenericFunctions';
|
||||||
|
|
||||||
import jwt from 'jsonwebtoken';
|
|
||||||
|
|
||||||
interface IGoogleAuthCredentials {
|
|
||||||
delegatedEmail?: string;
|
|
||||||
email: string;
|
|
||||||
inpersonate: boolean;
|
|
||||||
privateKey: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getAccessToken(
|
|
||||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IPollFunctions,
|
|
||||||
credentials: IGoogleAuthCredentials,
|
|
||||||
): Promise<IDataObject> {
|
|
||||||
//https://developers.google.com/identity/protocols/oauth2/service-account#httprest
|
|
||||||
|
|
||||||
const scopes = [
|
|
||||||
'https://www.googleapis.com/auth/drive',
|
|
||||||
'https://www.googleapis.com/auth/drive.appdata',
|
|
||||||
'https://www.googleapis.com/auth/drive.photos.readonly',
|
|
||||||
];
|
|
||||||
|
|
||||||
const now = moment().unix();
|
|
||||||
|
|
||||||
credentials.email = credentials.email.trim();
|
|
||||||
const privateKey = credentials.privateKey.replace(/\\n/g, '\n').trim();
|
|
||||||
|
|
||||||
const signature = jwt.sign(
|
|
||||||
{
|
|
||||||
iss: credentials.email,
|
|
||||||
sub: credentials.delegatedEmail || credentials.email,
|
|
||||||
scope: scopes.join(' '),
|
|
||||||
aud: 'https://oauth2.googleapis.com/token',
|
|
||||||
iat: now,
|
|
||||||
exp: now + 3600,
|
|
||||||
},
|
|
||||||
privateKey,
|
|
||||||
{
|
|
||||||
algorithm: 'RS256',
|
|
||||||
header: {
|
|
||||||
kid: privateKey,
|
|
||||||
typ: 'JWT',
|
|
||||||
alg: 'RS256',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const options: OptionsWithUri = {
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
},
|
|
||||||
method: 'POST',
|
|
||||||
form: {
|
|
||||||
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
|
||||||
assertion: signature,
|
|
||||||
},
|
|
||||||
uri: 'https://oauth2.googleapis.com/token',
|
|
||||||
json: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
return this.helpers.request(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function googleApiRequest(
|
export async function googleApiRequest(
|
||||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IPollFunctions,
|
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IPollFunctions,
|
||||||
method: string,
|
method: string,
|
||||||
resource: string,
|
resource: string,
|
||||||
|
|
||||||
body: any = {},
|
body: any = {},
|
||||||
qs: IDataObject = {},
|
qs: IDataObject = {},
|
||||||
uri?: string,
|
uri?: string,
|
||||||
@@ -111,10 +48,7 @@ export async function googleApiRequest(
|
|||||||
if (authenticationMethod === 'serviceAccount') {
|
if (authenticationMethod === 'serviceAccount') {
|
||||||
const credentials = await this.getCredentials('googleApi');
|
const credentials = await this.getCredentials('googleApi');
|
||||||
|
|
||||||
const { access_token } = await getAccessToken.call(
|
const { access_token } = await getGoogleAccessToken.call(this, credentials, 'drive');
|
||||||
this,
|
|
||||||
credentials as unknown as IGoogleAuthCredentials,
|
|
||||||
);
|
|
||||||
|
|
||||||
options.headers!.Authorization = `Bearer ${access_token}`;
|
options.headers!.Authorization = `Bearer ${access_token}`;
|
||||||
return await this.helpers.request(options);
|
return await this.helpers.request(options);
|
||||||
|
|||||||
105
packages/nodes-base/nodes/Google/GenericFunctions.ts
Normal file
105
packages/nodes-base/nodes/Google/GenericFunctions.ts
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
import type { IExecuteFunctions, IExecuteSingleFunctions, ILoadOptionsFunctions } from 'n8n-core';
|
||||||
|
import type { ICredentialTestFunctions, IDataObject, IPollFunctions } from 'n8n-workflow';
|
||||||
|
|
||||||
|
import type { OptionsWithUri } from 'request';
|
||||||
|
import moment from 'moment-timezone';
|
||||||
|
import * as jwt from 'jsonwebtoken';
|
||||||
|
|
||||||
|
const googleServiceAccountScopes = {
|
||||||
|
bigquery: ['https://www.googleapis.com/auth/bigquery'],
|
||||||
|
books: ['https://www.googleapis.com/auth/books'],
|
||||||
|
chat: ['https://www.googleapis.com/auth/chat.bot'],
|
||||||
|
docs: [
|
||||||
|
'https://www.googleapis.com/auth/documents',
|
||||||
|
'https://www.googleapis.com/auth/drive',
|
||||||
|
'https://www.googleapis.com/auth/drive.file',
|
||||||
|
],
|
||||||
|
drive: [
|
||||||
|
'https://www.googleapis.com/auth/drive',
|
||||||
|
'https://www.googleapis.com/auth/drive.appdata',
|
||||||
|
'https://www.googleapis.com/auth/drive.photos.readonly',
|
||||||
|
],
|
||||||
|
gmail: [
|
||||||
|
'https://www.googleapis.com/auth/gmail.labels',
|
||||||
|
'https://www.googleapis.com/auth/gmail.addons.current.action.compose',
|
||||||
|
'https://www.googleapis.com/auth/gmail.addons.current.message.action',
|
||||||
|
'https://mail.google.com/',
|
||||||
|
'https://www.googleapis.com/auth/gmail.modify',
|
||||||
|
'https://www.googleapis.com/auth/gmail.compose',
|
||||||
|
],
|
||||||
|
sheetV1: [
|
||||||
|
'https://www.googleapis.com/auth/drive',
|
||||||
|
'https://www.googleapis.com/auth/drive.file',
|
||||||
|
'https://www.googleapis.com/auth/spreadsheets',
|
||||||
|
],
|
||||||
|
sheetV2: [
|
||||||
|
'https://www.googleapis.com/auth/drive.file',
|
||||||
|
'https://www.googleapis.com/auth/spreadsheets',
|
||||||
|
'https://www.googleapis.com/auth/drive.metadata',
|
||||||
|
],
|
||||||
|
slides: [
|
||||||
|
'https://www.googleapis.com/auth/drive.file',
|
||||||
|
'https://www.googleapis.com/auth/presentations',
|
||||||
|
],
|
||||||
|
translate: [
|
||||||
|
'https://www.googleapis.com/auth/cloud-translation',
|
||||||
|
'https://www.googleapis.com/auth/cloud-platform',
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
type GoogleServiceAccount = keyof typeof googleServiceAccountScopes;
|
||||||
|
|
||||||
|
export async function getGoogleAccessToken(
|
||||||
|
this:
|
||||||
|
| IExecuteFunctions
|
||||||
|
| IExecuteSingleFunctions
|
||||||
|
| ILoadOptionsFunctions
|
||||||
|
| ICredentialTestFunctions
|
||||||
|
| IPollFunctions,
|
||||||
|
credentials: IDataObject,
|
||||||
|
service: GoogleServiceAccount,
|
||||||
|
): Promise<IDataObject> {
|
||||||
|
//https://developers.google.com/identity/protocols/oauth2/service-account#httprest
|
||||||
|
|
||||||
|
const scopes = googleServiceAccountScopes[service];
|
||||||
|
|
||||||
|
const privateKey = (credentials.privateKey as string).replace(/\\n/g, '\n').trim();
|
||||||
|
credentials.email = ((credentials.email as string) || '').trim();
|
||||||
|
|
||||||
|
const now = moment().unix();
|
||||||
|
|
||||||
|
const signature = jwt.sign(
|
||||||
|
{
|
||||||
|
iss: credentials.email,
|
||||||
|
sub: credentials.delegatedEmail || credentials.email,
|
||||||
|
scope: scopes.join(' '),
|
||||||
|
aud: 'https://oauth2.googleapis.com/token',
|
||||||
|
iat: now,
|
||||||
|
exp: now + 3600,
|
||||||
|
},
|
||||||
|
privateKey,
|
||||||
|
{
|
||||||
|
algorithm: 'RS256',
|
||||||
|
header: {
|
||||||
|
kid: privateKey,
|
||||||
|
typ: 'JWT',
|
||||||
|
alg: 'RS256',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const options: OptionsWithUri = {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
method: 'POST',
|
||||||
|
form: {
|
||||||
|
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
||||||
|
assertion: signature,
|
||||||
|
},
|
||||||
|
uri: 'https://oauth2.googleapis.com/token',
|
||||||
|
json: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.helpers.request(options);
|
||||||
|
}
|
||||||
@@ -4,7 +4,6 @@ import { simpleParser } from 'mailparser';
|
|||||||
|
|
||||||
import type {
|
import type {
|
||||||
IBinaryKeyData,
|
IBinaryKeyData,
|
||||||
ICredentialDataDecryptedObject,
|
|
||||||
IDataObject,
|
IDataObject,
|
||||||
IExecuteFunctions,
|
IExecuteFunctions,
|
||||||
IExecuteSingleFunctions,
|
IExecuteSingleFunctions,
|
||||||
@@ -16,10 +15,6 @@ import type {
|
|||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import { NodeApiError, NodeOperationError } from 'n8n-workflow';
|
import { NodeApiError, NodeOperationError } from 'n8n-workflow';
|
||||||
|
|
||||||
import moment from 'moment-timezone';
|
|
||||||
|
|
||||||
import jwt from 'jsonwebtoken';
|
|
||||||
|
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
|
|
||||||
import isEmpty from 'lodash.isempty';
|
import isEmpty from 'lodash.isempty';
|
||||||
@@ -44,62 +39,7 @@ export interface IAttachments {
|
|||||||
}
|
}
|
||||||
|
|
||||||
import MailComposer from 'nodemailer/lib/mail-composer';
|
import MailComposer from 'nodemailer/lib/mail-composer';
|
||||||
|
import { getGoogleAccessToken } from '../GenericFunctions';
|
||||||
async function getAccessToken(
|
|
||||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IPollFunctions,
|
|
||||||
credentials: ICredentialDataDecryptedObject,
|
|
||||||
): Promise<IDataObject> {
|
|
||||||
//https://developers.google.com/identity/protocols/oauth2/service-account#httprest
|
|
||||||
|
|
||||||
const scopes = [
|
|
||||||
'https://www.googleapis.com/auth/gmail.labels',
|
|
||||||
'https://www.googleapis.com/auth/gmail.addons.current.action.compose',
|
|
||||||
'https://www.googleapis.com/auth/gmail.addons.current.message.action',
|
|
||||||
'https://mail.google.com/',
|
|
||||||
'https://www.googleapis.com/auth/gmail.modify',
|
|
||||||
'https://www.googleapis.com/auth/gmail.compose',
|
|
||||||
];
|
|
||||||
|
|
||||||
const now = moment().unix();
|
|
||||||
|
|
||||||
credentials.email = (credentials.email as string).trim();
|
|
||||||
const privateKey = (credentials.privateKey as string).replace(/\\n/g, '\n').trim();
|
|
||||||
|
|
||||||
const signature = jwt.sign(
|
|
||||||
{
|
|
||||||
iss: credentials.email,
|
|
||||||
sub: credentials.delegatedEmail || credentials.email,
|
|
||||||
scope: scopes.join(' '),
|
|
||||||
aud: 'https://oauth2.googleapis.com/token',
|
|
||||||
iat: now,
|
|
||||||
exp: now + 3600,
|
|
||||||
},
|
|
||||||
privateKey,
|
|
||||||
{
|
|
||||||
algorithm: 'RS256',
|
|
||||||
header: {
|
|
||||||
kid: privateKey,
|
|
||||||
typ: 'JWT',
|
|
||||||
alg: 'RS256',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const options: OptionsWithUri = {
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
},
|
|
||||||
method: 'POST',
|
|
||||||
form: {
|
|
||||||
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
|
||||||
assertion: signature,
|
|
||||||
},
|
|
||||||
uri: 'https://oauth2.googleapis.com/token',
|
|
||||||
json: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
return this.helpers.request(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function googleApiRequest(
|
export async function googleApiRequest(
|
||||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IPollFunctions,
|
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IPollFunctions,
|
||||||
@@ -139,7 +79,7 @@ export async function googleApiRequest(
|
|||||||
const credentials = await this.getCredentials('googleApi');
|
const credentials = await this.getCredentials('googleApi');
|
||||||
credentialType = 'googleApi';
|
credentialType = 'googleApi';
|
||||||
|
|
||||||
const { access_token } = await getAccessToken.call(this, credentials);
|
const { access_token } = await getGoogleAccessToken.call(this, credentials, 'gmail');
|
||||||
|
|
||||||
(options.headers as IDataObject).Authorization = `Bearer ${access_token}`;
|
(options.headers as IDataObject).Authorization = `Bearer ${access_token}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import type { OptionsWithUri } from 'request';
|
import type { OptionsWithUri } from 'request';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ICredentialTestFunctions,
|
|
||||||
IDataObject,
|
IDataObject,
|
||||||
IExecuteFunctions,
|
IExecuteFunctions,
|
||||||
IExecuteSingleFunctions,
|
IExecuteSingleFunctions,
|
||||||
@@ -9,10 +8,7 @@ import type {
|
|||||||
JsonObject,
|
JsonObject,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import { NodeApiError } from 'n8n-workflow';
|
import { NodeApiError } from 'n8n-workflow';
|
||||||
|
import { getGoogleAccessToken } from '../../GenericFunctions';
|
||||||
import moment from 'moment-timezone';
|
|
||||||
|
|
||||||
import jwt from 'jsonwebtoken';
|
|
||||||
|
|
||||||
export interface IGoogleAuthCredentials {
|
export interface IGoogleAuthCredentials {
|
||||||
delegatedEmail?: string;
|
delegatedEmail?: string;
|
||||||
@@ -21,63 +17,6 @@ export interface IGoogleAuthCredentials {
|
|||||||
privateKey: string;
|
privateKey: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getAccessToken(
|
|
||||||
this:
|
|
||||||
| IExecuteFunctions
|
|
||||||
| IExecuteSingleFunctions
|
|
||||||
| ILoadOptionsFunctions
|
|
||||||
| ICredentialTestFunctions,
|
|
||||||
credentials: IGoogleAuthCredentials,
|
|
||||||
): Promise<IDataObject> {
|
|
||||||
//https://developers.google.com/identity/protocols/oauth2/service-account#httprest
|
|
||||||
|
|
||||||
const scopes = [
|
|
||||||
'https://www.googleapis.com/auth/drive',
|
|
||||||
'https://www.googleapis.com/auth/drive.file',
|
|
||||||
'https://www.googleapis.com/auth/spreadsheets',
|
|
||||||
];
|
|
||||||
|
|
||||||
const now = moment().unix();
|
|
||||||
|
|
||||||
credentials.email = credentials.email.trim();
|
|
||||||
const privateKey = credentials.privateKey.replace(/\\n/g, '\n').trim();
|
|
||||||
|
|
||||||
const signature = jwt.sign(
|
|
||||||
{
|
|
||||||
iss: credentials.email,
|
|
||||||
sub: credentials.delegatedEmail || credentials.email,
|
|
||||||
scope: scopes.join(' '),
|
|
||||||
aud: 'https://oauth2.googleapis.com/token',
|
|
||||||
iat: now,
|
|
||||||
exp: now + 3600,
|
|
||||||
},
|
|
||||||
privateKey,
|
|
||||||
{
|
|
||||||
algorithm: 'RS256',
|
|
||||||
header: {
|
|
||||||
kid: privateKey,
|
|
||||||
typ: 'JWT',
|
|
||||||
alg: 'RS256',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const options: OptionsWithUri = {
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
},
|
|
||||||
method: 'POST',
|
|
||||||
form: {
|
|
||||||
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
|
||||||
assertion: signature,
|
|
||||||
},
|
|
||||||
uri: 'https://oauth2.googleapis.com/token',
|
|
||||||
json: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
return this.helpers.request(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function googleApiRequest(
|
export async function googleApiRequest(
|
||||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
||||||
method: string,
|
method: string,
|
||||||
@@ -114,10 +53,7 @@ export async function googleApiRequest(
|
|||||||
if (authenticationMethod === 'serviceAccount') {
|
if (authenticationMethod === 'serviceAccount') {
|
||||||
const credentials = await this.getCredentials('googleApi');
|
const credentials = await this.getCredentials('googleApi');
|
||||||
|
|
||||||
const { access_token } = await getAccessToken.call(
|
const { access_token } = await getGoogleAccessToken.call(this, credentials, 'sheetV1');
|
||||||
this,
|
|
||||||
credentials as unknown as IGoogleAuthCredentials,
|
|
||||||
);
|
|
||||||
|
|
||||||
options.headers!.Authorization = `Bearer ${access_token}`;
|
options.headers!.Authorization = `Bearer ${access_token}`;
|
||||||
return await this.helpers.request(options);
|
return await this.helpers.request(options);
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ import type {
|
|||||||
} from './GoogleSheet';
|
} from './GoogleSheet';
|
||||||
import { GoogleSheet } from './GoogleSheet';
|
import { GoogleSheet } from './GoogleSheet';
|
||||||
|
|
||||||
import type { IGoogleAuthCredentials } from './GenericFunctions';
|
import { googleApiRequest, hexToRgb } from './GenericFunctions';
|
||||||
import { getAccessToken, googleApiRequest, hexToRgb } from './GenericFunctions';
|
|
||||||
|
|
||||||
import { versionDescription } from './versionDescription';
|
import { versionDescription } from './versionDescription';
|
||||||
|
import { getGoogleAccessToken } from '../../GenericFunctions';
|
||||||
|
|
||||||
export class GoogleSheetsV1 implements INodeType {
|
export class GoogleSheetsV1 implements INodeType {
|
||||||
description: INodeTypeDescription;
|
description: INodeTypeDescription;
|
||||||
@@ -71,10 +71,8 @@ export class GoogleSheetsV1 implements INodeType {
|
|||||||
credential: ICredentialsDecrypted,
|
credential: ICredentialsDecrypted,
|
||||||
): Promise<INodeCredentialTestResult> {
|
): Promise<INodeCredentialTestResult> {
|
||||||
try {
|
try {
|
||||||
const tokenRequest = await getAccessToken.call(
|
const tokenRequest = await getGoogleAccessToken.call(this, credential.data!, 'sheetV1');
|
||||||
this,
|
|
||||||
credential.data! as unknown as IGoogleAuthCredentials,
|
|
||||||
);
|
|
||||||
if (!tokenRequest.access_token) {
|
if (!tokenRequest.access_token) {
|
||||||
return {
|
return {
|
||||||
status: 'Error',
|
status: 'Error',
|
||||||
|
|||||||
@@ -4,18 +4,14 @@ import type {
|
|||||||
INodeCredentialTestResult,
|
INodeCredentialTestResult,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import type { IGoogleAuthCredentials } from '../transport';
|
import { getGoogleAccessToken } from '../../../GenericFunctions';
|
||||||
import { getAccessToken } from '../transport';
|
|
||||||
|
|
||||||
export async function googleApiCredentialTest(
|
export async function googleApiCredentialTest(
|
||||||
this: ICredentialTestFunctions,
|
this: ICredentialTestFunctions,
|
||||||
credential: ICredentialsDecrypted,
|
credential: ICredentialsDecrypted,
|
||||||
): Promise<INodeCredentialTestResult> {
|
): Promise<INodeCredentialTestResult> {
|
||||||
try {
|
try {
|
||||||
const tokenRequest = await getAccessToken.call(
|
const tokenRequest = await getGoogleAccessToken.call(this, credential.data!, 'sheetV2');
|
||||||
this,
|
|
||||||
credential.data! as unknown as IGoogleAuthCredentials,
|
|
||||||
);
|
|
||||||
if (!tokenRequest.access_token) {
|
if (!tokenRequest.access_token) {
|
||||||
return {
|
return {
|
||||||
status: 'Error',
|
status: 'Error',
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import type { OptionsWithUri } from 'request';
|
import type { OptionsWithUri } from 'request';
|
||||||
import type {
|
import type {
|
||||||
ICredentialTestFunctions,
|
|
||||||
IDataObject,
|
IDataObject,
|
||||||
IExecuteFunctions,
|
IExecuteFunctions,
|
||||||
IExecuteSingleFunctions,
|
IExecuteSingleFunctions,
|
||||||
@@ -9,73 +8,7 @@ import type {
|
|||||||
JsonObject,
|
JsonObject,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import { NodeApiError } from 'n8n-workflow';
|
import { NodeApiError } from 'n8n-workflow';
|
||||||
import moment from 'moment-timezone';
|
import { getGoogleAccessToken } from '../../../GenericFunctions';
|
||||||
import jwt from 'jsonwebtoken';
|
|
||||||
|
|
||||||
export interface IGoogleAuthCredentials {
|
|
||||||
delegatedEmail?: string;
|
|
||||||
email: string;
|
|
||||||
inpersonate: boolean;
|
|
||||||
privateKey: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getAccessToken(
|
|
||||||
this:
|
|
||||||
| IExecuteFunctions
|
|
||||||
| IExecuteSingleFunctions
|
|
||||||
| ILoadOptionsFunctions
|
|
||||||
| ICredentialTestFunctions
|
|
||||||
| IPollFunctions,
|
|
||||||
credentials: IGoogleAuthCredentials,
|
|
||||||
): Promise<IDataObject> {
|
|
||||||
//https://developers.google.com/identity/protocols/oauth2/service-account#httprest
|
|
||||||
|
|
||||||
const scopes = [
|
|
||||||
'https://www.googleapis.com/auth/drive.file',
|
|
||||||
'https://www.googleapis.com/auth/spreadsheets',
|
|
||||||
'https://www.googleapis.com/auth/drive.metadata',
|
|
||||||
];
|
|
||||||
|
|
||||||
const now = moment().unix();
|
|
||||||
|
|
||||||
credentials.email = credentials.email.trim();
|
|
||||||
const privateKey = credentials.privateKey.replace(/\\n/g, '\n').trim();
|
|
||||||
|
|
||||||
const signature = jwt.sign(
|
|
||||||
{
|
|
||||||
iss: credentials.email,
|
|
||||||
sub: credentials.delegatedEmail || credentials.email,
|
|
||||||
scope: scopes.join(' '),
|
|
||||||
aud: 'https://oauth2.googleapis.com/token',
|
|
||||||
iat: now,
|
|
||||||
exp: now + 3600,
|
|
||||||
},
|
|
||||||
privateKey,
|
|
||||||
{
|
|
||||||
algorithm: 'RS256',
|
|
||||||
header: {
|
|
||||||
kid: privateKey,
|
|
||||||
typ: 'JWT',
|
|
||||||
alg: 'RS256',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const options: OptionsWithUri = {
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
},
|
|
||||||
method: 'POST',
|
|
||||||
form: {
|
|
||||||
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
|
||||||
assertion: signature,
|
|
||||||
},
|
|
||||||
uri: 'https://oauth2.googleapis.com/token',
|
|
||||||
json: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
return this.helpers.request(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function apiRequest(
|
export async function apiRequest(
|
||||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IPollFunctions,
|
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IPollFunctions,
|
||||||
@@ -114,10 +47,7 @@ export async function apiRequest(
|
|||||||
if (authenticationMethod === 'serviceAccount') {
|
if (authenticationMethod === 'serviceAccount') {
|
||||||
const credentials = await this.getCredentials('googleApi');
|
const credentials = await this.getCredentials('googleApi');
|
||||||
|
|
||||||
const { access_token } = await getAccessToken.call(
|
const { access_token } = await getGoogleAccessToken.call(this, credentials, 'sheetV2');
|
||||||
this,
|
|
||||||
credentials as unknown as IGoogleAuthCredentials,
|
|
||||||
);
|
|
||||||
|
|
||||||
options.headers!.Authorization = `Bearer ${access_token}`;
|
options.headers!.Authorization = `Bearer ${access_token}`;
|
||||||
|
|
||||||
|
|||||||
@@ -8,68 +8,7 @@ import type {
|
|||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import { NodeApiError } from 'n8n-workflow';
|
import { NodeApiError } from 'n8n-workflow';
|
||||||
|
|
||||||
import moment from 'moment-timezone';
|
import { getGoogleAccessToken } from '../GenericFunctions';
|
||||||
|
|
||||||
import jwt from 'jsonwebtoken';
|
|
||||||
|
|
||||||
interface IGoogleAuthCredentials {
|
|
||||||
delegatedEmail?: string;
|
|
||||||
email: string;
|
|
||||||
inpersonate: boolean;
|
|
||||||
privateKey: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getAccessToken(
|
|
||||||
this: IExecuteFunctions | ILoadOptionsFunctions,
|
|
||||||
credentials: IGoogleAuthCredentials,
|
|
||||||
) {
|
|
||||||
// https://developers.google.com/identity/protocols/oauth2/service-account#httprest
|
|
||||||
|
|
||||||
const scopes = [
|
|
||||||
'https://www.googleapis.com/auth/drive.file',
|
|
||||||
'https://www.googleapis.com/auth/presentations',
|
|
||||||
];
|
|
||||||
|
|
||||||
const now = moment().unix();
|
|
||||||
|
|
||||||
credentials.email = credentials.email.trim();
|
|
||||||
const privateKey = credentials.privateKey.replace(/\\n/g, '\n').trim();
|
|
||||||
|
|
||||||
const signature = jwt.sign(
|
|
||||||
{
|
|
||||||
iss: credentials.email,
|
|
||||||
sub: credentials.email,
|
|
||||||
scope: scopes.join(' '),
|
|
||||||
aud: 'https://oauth2.googleapis.com/token',
|
|
||||||
iat: now,
|
|
||||||
exp: now + 3600,
|
|
||||||
},
|
|
||||||
privateKey,
|
|
||||||
{
|
|
||||||
algorithm: 'RS256',
|
|
||||||
header: {
|
|
||||||
kid: privateKey,
|
|
||||||
typ: 'JWT',
|
|
||||||
alg: 'RS256',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const options: OptionsWithUri = {
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
},
|
|
||||||
method: 'POST',
|
|
||||||
form: {
|
|
||||||
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
|
||||||
assertion: signature,
|
|
||||||
},
|
|
||||||
uri: 'https://oauth2.googleapis.com/token',
|
|
||||||
json: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
return this.helpers.request(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function googleApiRequest(
|
export async function googleApiRequest(
|
||||||
this: IExecuteFunctions | ILoadOptionsFunctions,
|
this: IExecuteFunctions | ILoadOptionsFunctions,
|
||||||
@@ -106,10 +45,7 @@ export async function googleApiRequest(
|
|||||||
if (authenticationMethod === 'serviceAccount') {
|
if (authenticationMethod === 'serviceAccount') {
|
||||||
const credentials = await this.getCredentials('googleApi');
|
const credentials = await this.getCredentials('googleApi');
|
||||||
|
|
||||||
const { access_token } = await getAccessToken.call(
|
const { access_token } = await getGoogleAccessToken.call(this, credentials, 'slides');
|
||||||
this,
|
|
||||||
credentials as unknown as IGoogleAuthCredentials,
|
|
||||||
);
|
|
||||||
options.headers.Authorization = `Bearer ${access_token}`;
|
options.headers.Authorization = `Bearer ${access_token}`;
|
||||||
return await this.helpers.request(options);
|
return await this.helpers.request(options);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -9,68 +9,7 @@ import type {
|
|||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import { NodeApiError } from 'n8n-workflow';
|
import { NodeApiError } from 'n8n-workflow';
|
||||||
|
|
||||||
import moment from 'moment-timezone';
|
import { getGoogleAccessToken } from '../GenericFunctions';
|
||||||
|
|
||||||
import jwt from 'jsonwebtoken';
|
|
||||||
|
|
||||||
interface IGoogleAuthCredentials {
|
|
||||||
delegatedEmail?: string;
|
|
||||||
email: string;
|
|
||||||
inpersonate: boolean;
|
|
||||||
privateKey: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getAccessToken(
|
|
||||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
|
||||||
credentials: IGoogleAuthCredentials,
|
|
||||||
): Promise<IDataObject> {
|
|
||||||
//https://developers.google.com/identity/protocols/oauth2/service-account#httprest
|
|
||||||
|
|
||||||
const scopes = [
|
|
||||||
'https://www.googleapis.com/auth/cloud-translation',
|
|
||||||
'https://www.googleapis.com/auth/cloud-platform',
|
|
||||||
];
|
|
||||||
|
|
||||||
const now = moment().unix();
|
|
||||||
|
|
||||||
credentials.email = credentials.email.trim();
|
|
||||||
const privateKey = credentials.privateKey.replace(/\\n/g, '\n').trim();
|
|
||||||
|
|
||||||
const signature = jwt.sign(
|
|
||||||
{
|
|
||||||
iss: credentials.email,
|
|
||||||
sub: credentials.email,
|
|
||||||
scope: scopes.join(' '),
|
|
||||||
aud: 'https://oauth2.googleapis.com/token',
|
|
||||||
iat: now,
|
|
||||||
exp: now + 3600,
|
|
||||||
},
|
|
||||||
privateKey,
|
|
||||||
{
|
|
||||||
algorithm: 'RS256',
|
|
||||||
header: {
|
|
||||||
kid: privateKey,
|
|
||||||
typ: 'JWT',
|
|
||||||
alg: 'RS256',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const options: OptionsWithUri = {
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
},
|
|
||||||
method: 'POST',
|
|
||||||
form: {
|
|
||||||
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
|
||||||
assertion: signature,
|
|
||||||
},
|
|
||||||
uri: 'https://oauth2.googleapis.com/token',
|
|
||||||
json: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
return this.helpers.request(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function googleApiRequest(
|
export async function googleApiRequest(
|
||||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
||||||
@@ -108,16 +47,12 @@ export async function googleApiRequest(
|
|||||||
if (authenticationMethod === 'serviceAccount') {
|
if (authenticationMethod === 'serviceAccount') {
|
||||||
const credentials = await this.getCredentials('googleApi');
|
const credentials = await this.getCredentials('googleApi');
|
||||||
|
|
||||||
const { access_token } = await getAccessToken.call(
|
const { access_token } = await getGoogleAccessToken.call(this, credentials, 'translate');
|
||||||
this,
|
|
||||||
credentials as unknown as IGoogleAuthCredentials,
|
|
||||||
);
|
|
||||||
|
|
||||||
options.headers!.Authorization = `Bearer ${access_token}`;
|
options.headers!.Authorization = `Bearer ${access_token}`;
|
||||||
//@ts-ignore
|
|
||||||
return await this.helpers.request(options);
|
return await this.helpers.request(options);
|
||||||
} else {
|
} else {
|
||||||
//@ts-ignore
|
|
||||||
return await this.helpers.requestOAuth2.call(this, 'googleTranslateOAuth2Api', options);
|
return await this.helpers.requestOAuth2.call(this, 'googleTranslateOAuth2Api', options);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user