mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-25 04:34:06 -08:00
feat(core): Support for google service account in HTTP node
This commit is contained in:
parent
49d838f628
commit
0b48088296
|
@ -1,9 +1,22 @@
|
|||
import type { ICredentialType, INodeProperties } from 'n8n-workflow';
|
||||
import type {
|
||||
ICredentialDataDecryptedObject,
|
||||
ICredentialType,
|
||||
IHttpRequestOptions,
|
||||
INodeProperties,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import moment from 'moment-timezone';
|
||||
|
||||
import jwt from 'jsonwebtoken';
|
||||
|
||||
import type { AxiosRequestConfig } from 'axios';
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
export class GoogleApi implements ICredentialType {
|
||||
name = 'googleApi';
|
||||
|
||||
displayName = 'Google API';
|
||||
displayName = 'Google Service Account API';
|
||||
|
||||
documentationUrl = 'google/service-account';
|
||||
|
||||
|
@ -52,5 +65,101 @@ export class GoogleApi implements ICredentialType {
|
|||
description:
|
||||
'The email address of the user for which the application is requesting delegated access',
|
||||
},
|
||||
{
|
||||
displayName: 'Set up for use in HTTP Request node',
|
||||
name: 'httpNode',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
displayName:
|
||||
"When using the HTTP Request node, you must specify the scopes you want to send. In other nodes, they're added automatically",
|
||||
name: 'httpWarning',
|
||||
type: 'notice',
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
httpNode: [true],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Scope(s)',
|
||||
name: 'scopes',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description:
|
||||
'You can find the scopes for services <a href="https://developers.google.com/identity/protocols/oauth2/scopes" target="_blank">here</a>',
|
||||
displayOptions: {
|
||||
show: {
|
||||
httpNode: [true],
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
async authenticate(
|
||||
credentials: ICredentialDataDecryptedObject,
|
||||
requestOptions: IHttpRequestOptions,
|
||||
): Promise<IHttpRequestOptions> {
|
||||
if (!credentials.httpNode) return requestOptions;
|
||||
|
||||
const privateKey = (credentials.privateKey as string).replace(/\\n/g, '\n').trim();
|
||||
const credentialsScopes = (credentials.scopes as string).replace(/\\n/g, '\n').trim();
|
||||
credentials.email = (credentials.email as string).trim();
|
||||
|
||||
const regex = /[,\s\n]+/;
|
||||
const scopes = credentialsScopes
|
||||
.split(regex)
|
||||
.filter((scope) => scope)
|
||||
.join(' ');
|
||||
|
||||
const now = moment().unix();
|
||||
|
||||
const signature = jwt.sign(
|
||||
{
|
||||
iss: credentials.email,
|
||||
sub: credentials.delegatedEmail || credentials.email,
|
||||
scope: scopes,
|
||||
aud: 'https://oauth2.googleapis.com/token',
|
||||
iat: now,
|
||||
exp: now + 3600,
|
||||
},
|
||||
privateKey,
|
||||
{
|
||||
algorithm: 'RS256',
|
||||
header: {
|
||||
kid: privateKey,
|
||||
typ: 'JWT',
|
||||
alg: 'RS256',
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const axiosRequestConfig: AxiosRequestConfig = {
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
method: 'POST',
|
||||
data: new URLSearchParams({
|
||||
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
||||
assertion: signature,
|
||||
}).toString(),
|
||||
url: 'https://oauth2.googleapis.com/token',
|
||||
};
|
||||
|
||||
const result = await axios(axiosRequestConfig);
|
||||
|
||||
const { access_token } = result.data;
|
||||
|
||||
const requestOptionsWithAuth: IHttpRequestOptions = {
|
||||
...requestOptions,
|
||||
headers: {
|
||||
...requestOptions.headers,
|
||||
Authorization: `Bearer ${access_token}`,
|
||||
},
|
||||
};
|
||||
|
||||
return requestOptionsWithAuth;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -137,6 +137,18 @@ export class HttpRequestV3 implements INodeType {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName:
|
||||
'Make sure you have specified the scope(s) for the Service Account in the credential',
|
||||
name: 'googleApiWarning',
|
||||
type: 'notice',
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
nodeCredentialType: ['googleApi'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Generic Auth Type',
|
||||
name: 'genericAuthType',
|
||||
|
|
Loading…
Reference in a new issue