mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-23 11:44:06 -08:00
fix(Ghost Node): Fix post tags and add credential tests (#3278)
* Renamed Tag IDs to Tags and changed the value to tag.name * Updated credentials to use new system * Nodelinter changes
This commit is contained in:
parent
7090a79b5d
commit
a14d85ea48
|
@ -1,8 +1,12 @@
|
|||
import {
|
||||
ICredentialDataDecryptedObject,
|
||||
ICredentialTestRequest,
|
||||
ICredentialType,
|
||||
IHttpRequestOptions,
|
||||
INodeProperties,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import jwt from 'jsonwebtoken';
|
||||
export class GhostAdminApi implements ICredentialType {
|
||||
name = 'ghostAdminApi';
|
||||
displayName = 'Ghost Admin API';
|
||||
|
@ -22,4 +26,27 @@ export class GhostAdminApi implements ICredentialType {
|
|||
default: '',
|
||||
},
|
||||
];
|
||||
|
||||
async authenticate(credentials: ICredentialDataDecryptedObject, requestOptions: IHttpRequestOptions): Promise<IHttpRequestOptions> {
|
||||
const [id, secret] = (credentials.apiKey as string).split(':');
|
||||
const token = jwt.sign({}, Buffer.from(secret, 'hex'), {
|
||||
keyid: id,
|
||||
algorithm: 'HS256',
|
||||
expiresIn: '5m',
|
||||
audience: `/v2/admin/`,
|
||||
});
|
||||
|
||||
requestOptions.headers = {
|
||||
...requestOptions.headers,
|
||||
Authorization: `Ghost ${token}`,
|
||||
};
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
test: ICredentialTestRequest = {
|
||||
request: {
|
||||
baseURL: '={{$credentials.url}}',
|
||||
url: '/ghost/api/v2/admin/pages/',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import {
|
||||
ICredentialDataDecryptedObject,
|
||||
ICredentialTestRequest,
|
||||
ICredentialType,
|
||||
IHttpRequestOptions,
|
||||
INodeProperties,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
|
@ -22,4 +25,18 @@ export class GhostContentApi implements ICredentialType {
|
|||
default: '',
|
||||
},
|
||||
];
|
||||
async authenticate(credentials: ICredentialDataDecryptedObject, requestOptions: IHttpRequestOptions): Promise<IHttpRequestOptions> {
|
||||
requestOptions.qs = {
|
||||
...requestOptions.qs,
|
||||
'key': credentials.apiKey,
|
||||
};
|
||||
return requestOptions;
|
||||
}
|
||||
test: ICredentialTestRequest = {
|
||||
request: {
|
||||
baseURL: '={{$credentials.url}}',
|
||||
url: '/ghost/api/v3/content/settings/',
|
||||
method: 'GET',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -10,38 +10,30 @@ import {
|
|||
} from 'n8n-core';
|
||||
|
||||
import {
|
||||
IDataObject, NodeApiError,
|
||||
IDataObject,
|
||||
JsonObject,
|
||||
NodeApiError,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import jwt from 'jsonwebtoken';
|
||||
|
||||
export async function ghostApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, endpoint: string, body: any = {}, query: IDataObject = {}, uri?: string): Promise<any> { // tslint:disable-line:no-any
|
||||
|
||||
const source = this.getNodeParameter('source', 0) as string;
|
||||
|
||||
let credentials;
|
||||
let version;
|
||||
let token;
|
||||
let credentialType;
|
||||
|
||||
if (source === 'contentApi') {
|
||||
//https://ghost.org/faq/api-versioning/
|
||||
version = 'v3';
|
||||
credentials = await this.getCredentials('ghostContentApi');
|
||||
query.key = credentials.apiKey as string;
|
||||
credentialType = 'ghostContentApi';
|
||||
} else {
|
||||
version = 'v2';
|
||||
credentials = await this.getCredentials('ghostAdminApi');
|
||||
// Create the token (including decoding secret)
|
||||
const [id, secret] = (credentials.apiKey as string).split(':');
|
||||
|
||||
token = jwt.sign({}, Buffer.from(secret, 'hex'), {
|
||||
keyid: id,
|
||||
algorithm: 'HS256',
|
||||
expiresIn: '5m',
|
||||
audience: `/${version}/admin/`,
|
||||
});
|
||||
credentialType = 'ghostAdminApi';
|
||||
}
|
||||
|
||||
credentials = await this.getCredentials(credentialType);
|
||||
|
||||
const options: OptionsWithUri = {
|
||||
method,
|
||||
qs: query,
|
||||
|
@ -50,17 +42,10 @@ export async function ghostApiRequest(this: IHookFunctions | IExecuteFunctions |
|
|||
json: true,
|
||||
};
|
||||
|
||||
if (token) {
|
||||
options.headers = {
|
||||
Authorization: `Ghost ${token}`,
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
return await this.helpers.request!(options);
|
||||
|
||||
} catch (error) {
|
||||
throw new NodeApiError(this.getNode(), error);
|
||||
return await this.helpers.requestWithAuthentication.call(this, credentialType, options);
|
||||
} catch(error) {
|
||||
throw new NodeApiError(this.getNode(), error as JsonObject);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ export class Ghost implements INodeType {
|
|||
description: INodeTypeDescription = {
|
||||
displayName: 'Ghost',
|
||||
name: 'ghost',
|
||||
icon: 'file:ghost.png',
|
||||
icon: 'file:ghost.svg',
|
||||
group: ['input'],
|
||||
version: 1,
|
||||
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
||||
|
@ -91,8 +91,9 @@ export class Ghost implements INodeType {
|
|||
value: 'post',
|
||||
},
|
||||
],
|
||||
noDataExpression: true,
|
||||
default: 'post',
|
||||
description: 'The resource to operate on.',
|
||||
description: 'The resource to operate on',
|
||||
},
|
||||
...postOperations,
|
||||
...postFields,
|
||||
|
@ -137,7 +138,7 @@ export class Ghost implements INodeType {
|
|||
for (const tag of tags) {
|
||||
returnData.push({
|
||||
name: tag.name,
|
||||
value: tag.id,
|
||||
value: tag.name,
|
||||
});
|
||||
}
|
||||
return returnData;
|
||||
|
|
|
@ -6,6 +6,7 @@ export const postOperations: INodeProperties[] = [
|
|||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
noDataExpression: true,
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
|
@ -30,11 +31,12 @@ export const postOperations: INodeProperties[] = [
|
|||
},
|
||||
],
|
||||
default: 'get',
|
||||
description: 'The operation to perform.',
|
||||
description: 'The operation to perform',
|
||||
},
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
noDataExpression: true,
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
|
@ -74,7 +76,7 @@ export const postOperations: INodeProperties[] = [
|
|||
},
|
||||
],
|
||||
default: 'get',
|
||||
description: 'The operation to perform.',
|
||||
description: 'The operation to perform',
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -256,12 +258,6 @@ export const postFields: INodeProperties[] = [
|
|||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Open Graph Title',
|
||||
name: 'og_title',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Open Graph Image',
|
||||
name: 'og_image',
|
||||
|
@ -270,6 +266,12 @@ export const postFields: INodeProperties[] = [
|
|||
description: 'URL of the image',
|
||||
|
||||
},
|
||||
{
|
||||
displayName: 'Open Graph Title',
|
||||
name: 'og_title',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Published At',
|
||||
name: 'published_at',
|
||||
|
@ -303,7 +305,7 @@ export const postFields: INodeProperties[] = [
|
|||
default: 'draft',
|
||||
},
|
||||
{
|
||||
displayName: 'Tags IDs',
|
||||
displayName: 'Tags',
|
||||
name: 'tags',
|
||||
type: 'multiOptions',
|
||||
typeOptions: {
|
||||
|
@ -365,7 +367,7 @@ export const postFields: INodeProperties[] = [
|
|||
displayName: 'By',
|
||||
name: 'by',
|
||||
type: 'options',
|
||||
default: '',
|
||||
default: 'id',
|
||||
required: true,
|
||||
options: [
|
||||
{
|
||||
|
@ -846,12 +848,6 @@ export const postFields: INodeProperties[] = [
|
|||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Open Graph Title',
|
||||
name: 'og_title',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Open Graph Image',
|
||||
name: 'og_image',
|
||||
|
@ -859,6 +855,12 @@ export const postFields: INodeProperties[] = [
|
|||
default: '',
|
||||
description: 'URL of the image',
|
||||
},
|
||||
{
|
||||
displayName: 'Open Graph Title',
|
||||
name: 'og_title',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Published At',
|
||||
name: 'published_at',
|
||||
|
@ -892,7 +894,7 @@ export const postFields: INodeProperties[] = [
|
|||
default: 'draft',
|
||||
},
|
||||
{
|
||||
displayName: 'Tags IDs',
|
||||
displayName: 'Tags',
|
||||
name: 'tags',
|
||||
type: 'multiOptions',
|
||||
typeOptions: {
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.2 KiB |
1
packages/nodes-base/nodes/Ghost/ghost.svg
Normal file
1
packages/nodes-base/nodes/Ghost/ghost.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 151 151" fill="#fff" fill-rule="evenodd" stroke="#000" stroke-linecap="round" stroke-linejoin="round"><use xlink:href="#A" x=".5" y=".5"/><symbol id="A" overflow="visible"><g fill-rule="nonzero"><path d="M0 22.5C0 10.035 10.035 0 22.5 0h105C139.965 0 150 10.035 150 22.5v105c0 12.465-10.035 22.5-22.5 22.5h-105C10.035 150 0 139.965 0 127.5z" stroke="none" fill="#e8e9eb"/><path d="M29.59 39.258h54.785zm72.07 0h17.871zM29.59 75.293h90.82zm0 35.449h36.035zm54.785 0h36.035z" stroke="#3d515b" stroke-linejoin="miter" fill="#000" stroke-width="17.871"/></g></symbol></svg>
|
After Width: | Height: | Size: 665 B |
Loading…
Reference in a new issue