mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-24 04:04:06 -08:00
refactor(core): Google service account remove duplicated functions (no-changelog) (#6368)
This commit is contained in:
parent
3a6af3b2a2
commit
05c4229cd7
|
@ -8,64 +8,12 @@ import type {
|
|||
JsonObject,
|
||||
} from 'n8n-workflow';
|
||||
import { NodeApiError, NodeOperationError } from 'n8n-workflow';
|
||||
|
||||
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);
|
||||
}
|
||||
import { getGoogleAccessToken } from '../../GenericFunctions';
|
||||
|
||||
export async function googleApiRequest(
|
||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
||||
method: string,
|
||||
resource: string,
|
||||
|
||||
body: any = {},
|
||||
qs: IDataObject = {},
|
||||
uri?: string,
|
||||
|
@ -102,7 +50,7 @@ export async function googleApiRequest(
|
|||
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}`;
|
||||
return await this.helpers.request(options);
|
||||
|
|
|
@ -1,58 +1,9 @@
|
|||
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 { IDataObject, JsonObject } from 'n8n-workflow';
|
||||
import { NodeApiError, NodeOperationError } from 'n8n-workflow';
|
||||
|
||||
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);
|
||||
}
|
||||
import { getGoogleAccessToken } from '../../../GenericFunctions';
|
||||
|
||||
export async function googleApiRequest(
|
||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
||||
|
@ -94,7 +45,7 @@ export async function googleApiRequest(
|
|||
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}`;
|
||||
return await this.helpers.request(options);
|
||||
|
|
|
@ -8,72 +8,12 @@ import type {
|
|||
JsonObject,
|
||||
} from 'n8n-workflow';
|
||||
import { NodeApiError } from 'n8n-workflow';
|
||||
|
||||
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);
|
||||
}
|
||||
import { getGoogleAccessToken } from '../GenericFunctions';
|
||||
|
||||
export async function googleApiRequest(
|
||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
||||
method: string,
|
||||
resource: string,
|
||||
|
||||
body: any = {},
|
||||
qs: IDataObject = {},
|
||||
uri?: string,
|
||||
|
@ -108,10 +48,7 @@ export async function googleApiRequest(
|
|||
privateKey: string;
|
||||
};
|
||||
|
||||
const { access_token } = await getAccessToken.call(
|
||||
this,
|
||||
credentials as unknown as IGoogleAuthCredentials,
|
||||
);
|
||||
const { access_token } = await getGoogleAccessToken.call(this, credentials, 'books');
|
||||
|
||||
options.headers!.Authorization = `Bearer ${access_token}`;
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import type { OptionsWithUri } from 'request';
|
||||
|
||||
import type {
|
||||
ICredentialTestFunctions,
|
||||
IDataObject,
|
||||
IExecuteFunctions,
|
||||
IExecuteSingleFunctions,
|
||||
|
@ -11,69 +10,7 @@ import type {
|
|||
} from 'n8n-workflow';
|
||||
import { NodeApiError } from 'n8n-workflow';
|
||||
|
||||
import moment from 'moment-timezone';
|
||||
|
||||
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);
|
||||
}
|
||||
import { getGoogleAccessToken } from '../GenericFunctions';
|
||||
|
||||
export async function googleApiRequest(
|
||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
||||
|
@ -112,10 +49,7 @@ export async function googleApiRequest(
|
|||
} else {
|
||||
const credentials = await this.getCredentials('googleApi');
|
||||
|
||||
const { access_token } = await getAccessToken.call(
|
||||
this,
|
||||
credentials as unknown as IGoogleAuthCredentials,
|
||||
);
|
||||
const { access_token } = await getGoogleAccessToken.call(this, credentials, 'chat');
|
||||
options.headers!.Authorization = `Bearer ${access_token}`;
|
||||
responseData = await this.helpers.request(options);
|
||||
}
|
||||
|
|
|
@ -8,69 +8,7 @@ import type {
|
|||
} from 'n8n-workflow';
|
||||
import { NodeApiError } from 'n8n-workflow';
|
||||
|
||||
import moment from 'moment-timezone';
|
||||
|
||||
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);
|
||||
}
|
||||
import { getGoogleAccessToken } from '../GenericFunctions';
|
||||
|
||||
export async function googleApiRequest(
|
||||
this: IExecuteFunctions | ILoadOptionsFunctions,
|
||||
|
@ -104,10 +42,7 @@ export async function googleApiRequest(
|
|||
if (authenticationMethod === 'serviceAccount') {
|
||||
const credentials = await this.getCredentials('googleApi');
|
||||
|
||||
const { access_token } = await getAccessToken.call(
|
||||
this,
|
||||
credentials as unknown as IGoogleAuthCredentials,
|
||||
);
|
||||
const { access_token } = await getGoogleAccessToken.call(this, credentials, 'docs');
|
||||
|
||||
options.headers!.Authorization = `Bearer ${access_token}`;
|
||||
return await this.helpers.request(options);
|
||||
|
|
|
@ -10,75 +10,12 @@ import type {
|
|||
} from 'n8n-workflow';
|
||||
import { NodeApiError } from 'n8n-workflow';
|
||||
|
||||
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 | 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);
|
||||
}
|
||||
import { getGoogleAccessToken } from '../GenericFunctions';
|
||||
|
||||
export async function googleApiRequest(
|
||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IPollFunctions,
|
||||
method: string,
|
||||
resource: string,
|
||||
|
||||
body: any = {},
|
||||
qs: IDataObject = {},
|
||||
uri?: string,
|
||||
|
@ -111,10 +48,7 @@ export async function googleApiRequest(
|
|||
if (authenticationMethod === 'serviceAccount') {
|
||||
const credentials = await this.getCredentials('googleApi');
|
||||
|
||||
const { access_token } = await getAccessToken.call(
|
||||
this,
|
||||
credentials as unknown as IGoogleAuthCredentials,
|
||||
);
|
||||
const { access_token } = await getGoogleAccessToken.call(this, credentials, 'drive');
|
||||
|
||||
options.headers!.Authorization = `Bearer ${access_token}`;
|
||||
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 {
|
||||
IBinaryKeyData,
|
||||
ICredentialDataDecryptedObject,
|
||||
IDataObject,
|
||||
IExecuteFunctions,
|
||||
IExecuteSingleFunctions,
|
||||
|
@ -16,10 +15,6 @@ import type {
|
|||
} from 'n8n-workflow';
|
||||
import { NodeApiError, NodeOperationError } from 'n8n-workflow';
|
||||
|
||||
import moment from 'moment-timezone';
|
||||
|
||||
import jwt from 'jsonwebtoken';
|
||||
|
||||
import { DateTime } from 'luxon';
|
||||
|
||||
import isEmpty from 'lodash.isempty';
|
||||
|
@ -44,62 +39,7 @@ export interface IAttachments {
|
|||
}
|
||||
|
||||
import MailComposer from 'nodemailer/lib/mail-composer';
|
||||
|
||||
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);
|
||||
}
|
||||
import { getGoogleAccessToken } from '../GenericFunctions';
|
||||
|
||||
export async function googleApiRequest(
|
||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IPollFunctions,
|
||||
|
@ -139,7 +79,7 @@ export async function googleApiRequest(
|
|||
const credentials = await this.getCredentials('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}`;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import type { OptionsWithUri } from 'request';
|
||||
|
||||
import type {
|
||||
ICredentialTestFunctions,
|
||||
IDataObject,
|
||||
IExecuteFunctions,
|
||||
IExecuteSingleFunctions,
|
||||
|
@ -9,10 +8,7 @@ import type {
|
|||
JsonObject,
|
||||
} from 'n8n-workflow';
|
||||
import { NodeApiError } from 'n8n-workflow';
|
||||
|
||||
import moment from 'moment-timezone';
|
||||
|
||||
import jwt from 'jsonwebtoken';
|
||||
import { getGoogleAccessToken } from '../../GenericFunctions';
|
||||
|
||||
export interface IGoogleAuthCredentials {
|
||||
delegatedEmail?: string;
|
||||
|
@ -21,63 +17,6 @@ export interface IGoogleAuthCredentials {
|
|||
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(
|
||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
||||
method: string,
|
||||
|
@ -114,10 +53,7 @@ export async function googleApiRequest(
|
|||
if (authenticationMethod === 'serviceAccount') {
|
||||
const credentials = await this.getCredentials('googleApi');
|
||||
|
||||
const { access_token } = await getAccessToken.call(
|
||||
this,
|
||||
credentials as unknown as IGoogleAuthCredentials,
|
||||
);
|
||||
const { access_token } = await getGoogleAccessToken.call(this, credentials, 'sheetV1');
|
||||
|
||||
options.headers!.Authorization = `Bearer ${access_token}`;
|
||||
return await this.helpers.request(options);
|
||||
|
|
|
@ -22,10 +22,10 @@ import type {
|
|||
} from './GoogleSheet';
|
||||
import { GoogleSheet } from './GoogleSheet';
|
||||
|
||||
import type { IGoogleAuthCredentials } from './GenericFunctions';
|
||||
import { getAccessToken, googleApiRequest, hexToRgb } from './GenericFunctions';
|
||||
import { googleApiRequest, hexToRgb } from './GenericFunctions';
|
||||
|
||||
import { versionDescription } from './versionDescription';
|
||||
import { getGoogleAccessToken } from '../../GenericFunctions';
|
||||
|
||||
export class GoogleSheetsV1 implements INodeType {
|
||||
description: INodeTypeDescription;
|
||||
|
@ -71,10 +71,8 @@ export class GoogleSheetsV1 implements INodeType {
|
|||
credential: ICredentialsDecrypted,
|
||||
): Promise<INodeCredentialTestResult> {
|
||||
try {
|
||||
const tokenRequest = await getAccessToken.call(
|
||||
this,
|
||||
credential.data! as unknown as IGoogleAuthCredentials,
|
||||
);
|
||||
const tokenRequest = await getGoogleAccessToken.call(this, credential.data!, 'sheetV1');
|
||||
|
||||
if (!tokenRequest.access_token) {
|
||||
return {
|
||||
status: 'Error',
|
||||
|
|
|
@ -4,18 +4,14 @@ import type {
|
|||
INodeCredentialTestResult,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import type { IGoogleAuthCredentials } from '../transport';
|
||||
import { getAccessToken } from '../transport';
|
||||
import { getGoogleAccessToken } from '../../../GenericFunctions';
|
||||
|
||||
export async function googleApiCredentialTest(
|
||||
this: ICredentialTestFunctions,
|
||||
credential: ICredentialsDecrypted,
|
||||
): Promise<INodeCredentialTestResult> {
|
||||
try {
|
||||
const tokenRequest = await getAccessToken.call(
|
||||
this,
|
||||
credential.data! as unknown as IGoogleAuthCredentials,
|
||||
);
|
||||
const tokenRequest = await getGoogleAccessToken.call(this, credential.data!, 'sheetV2');
|
||||
if (!tokenRequest.access_token) {
|
||||
return {
|
||||
status: 'Error',
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import type { OptionsWithUri } from 'request';
|
||||
import type {
|
||||
ICredentialTestFunctions,
|
||||
IDataObject,
|
||||
IExecuteFunctions,
|
||||
IExecuteSingleFunctions,
|
||||
|
@ -9,73 +8,7 @@ import type {
|
|||
JsonObject,
|
||||
} from 'n8n-workflow';
|
||||
import { NodeApiError } from 'n8n-workflow';
|
||||
import moment from 'moment-timezone';
|
||||
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);
|
||||
}
|
||||
import { getGoogleAccessToken } from '../../../GenericFunctions';
|
||||
|
||||
export async function apiRequest(
|
||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IPollFunctions,
|
||||
|
@ -114,10 +47,7 @@ export async function apiRequest(
|
|||
if (authenticationMethod === 'serviceAccount') {
|
||||
const credentials = await this.getCredentials('googleApi');
|
||||
|
||||
const { access_token } = await getAccessToken.call(
|
||||
this,
|
||||
credentials as unknown as IGoogleAuthCredentials,
|
||||
);
|
||||
const { access_token } = await getGoogleAccessToken.call(this, credentials, 'sheetV2');
|
||||
|
||||
options.headers!.Authorization = `Bearer ${access_token}`;
|
||||
|
||||
|
|
|
@ -8,68 +8,7 @@ import type {
|
|||
} from 'n8n-workflow';
|
||||
import { NodeApiError } from 'n8n-workflow';
|
||||
|
||||
import moment from 'moment-timezone';
|
||||
|
||||
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);
|
||||
}
|
||||
import { getGoogleAccessToken } from '../GenericFunctions';
|
||||
|
||||
export async function googleApiRequest(
|
||||
this: IExecuteFunctions | ILoadOptionsFunctions,
|
||||
|
@ -106,10 +45,7 @@ export async function googleApiRequest(
|
|||
if (authenticationMethod === 'serviceAccount') {
|
||||
const credentials = await this.getCredentials('googleApi');
|
||||
|
||||
const { access_token } = await getAccessToken.call(
|
||||
this,
|
||||
credentials as unknown as IGoogleAuthCredentials,
|
||||
);
|
||||
const { access_token } = await getGoogleAccessToken.call(this, credentials, 'slides');
|
||||
options.headers.Authorization = `Bearer ${access_token}`;
|
||||
return await this.helpers.request(options);
|
||||
} else {
|
||||
|
|
|
@ -9,68 +9,7 @@ import type {
|
|||
} from 'n8n-workflow';
|
||||
import { NodeApiError } from 'n8n-workflow';
|
||||
|
||||
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/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);
|
||||
}
|
||||
import { getGoogleAccessToken } from '../GenericFunctions';
|
||||
|
||||
export async function googleApiRequest(
|
||||
this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions,
|
||||
|
@ -108,16 +47,12 @@ export async function googleApiRequest(
|
|||
if (authenticationMethod === 'serviceAccount') {
|
||||
const credentials = await this.getCredentials('googleApi');
|
||||
|
||||
const { access_token } = await getAccessToken.call(
|
||||
this,
|
||||
credentials as unknown as IGoogleAuthCredentials,
|
||||
);
|
||||
const { access_token } = await getGoogleAccessToken.call(this, credentials, 'translate');
|
||||
|
||||
options.headers!.Authorization = `Bearer ${access_token}`;
|
||||
//@ts-ignore
|
||||
|
||||
return await this.helpers.request(options);
|
||||
} else {
|
||||
//@ts-ignore
|
||||
return await this.helpers.requestOAuth2.call(this, 'googleTranslateOAuth2Api', options);
|
||||
}
|
||||
} catch (error) {
|
||||
|
|
Loading…
Reference in a new issue