mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 01:56:46 +00:00
feat(Azure Cosmos DB Node): New node (#14156)
Co-authored-by: feelgood-interface <feelgood.interface@gmail.com>
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
import { createHmac } from 'crypto';
|
||||
import type {
|
||||
ICredentialDataDecryptedObject,
|
||||
ICredentialType,
|
||||
ICredentialTestRequest,
|
||||
IHttpRequestOptions,
|
||||
INodeProperties,
|
||||
IRequestOptions,
|
||||
} from 'n8n-workflow';
|
||||
import { OperationalError } from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
CURRENT_VERSION,
|
||||
HeaderConstants,
|
||||
RESOURCE_TYPES,
|
||||
} from '../nodes/Microsoft/AzureCosmosDb/helpers/constants';
|
||||
|
||||
export class MicrosoftAzureCosmosDbSharedKeyApi implements ICredentialType {
|
||||
name = 'microsoftAzureCosmosDbSharedKeyApi';
|
||||
|
||||
displayName = 'Microsoft Azure Cosmos DB API';
|
||||
|
||||
documentationUrl = 'microsoftAzureCosmosdb';
|
||||
|
||||
properties: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Account',
|
||||
name: 'account',
|
||||
default: '',
|
||||
description: 'Account name',
|
||||
required: true,
|
||||
type: 'string',
|
||||
},
|
||||
{
|
||||
displayName: 'Key',
|
||||
name: 'key',
|
||||
default: '',
|
||||
description: 'Account key',
|
||||
required: true,
|
||||
type: 'string',
|
||||
typeOptions: {
|
||||
password: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Database',
|
||||
name: 'database',
|
||||
default: '',
|
||||
description: 'Database name',
|
||||
required: true,
|
||||
type: 'string',
|
||||
},
|
||||
];
|
||||
|
||||
async authenticate(
|
||||
credentials: ICredentialDataDecryptedObject,
|
||||
requestOptions: IHttpRequestOptions,
|
||||
): Promise<IHttpRequestOptions> {
|
||||
const date = new Date().toUTCString();
|
||||
|
||||
requestOptions.headers ??= {};
|
||||
requestOptions.headers = {
|
||||
...requestOptions.headers,
|
||||
'x-ms-date': date,
|
||||
'x-ms-version': CURRENT_VERSION,
|
||||
'Cache-Control': 'no-cache',
|
||||
};
|
||||
|
||||
// HttpRequest node uses IRequestOptions.uri
|
||||
const url = new URL(
|
||||
(requestOptions as IRequestOptions).uri ?? requestOptions.baseURL + requestOptions.url,
|
||||
);
|
||||
|
||||
const pathSegments = url.pathname.split('/').filter(Boolean);
|
||||
|
||||
const foundResource = RESOURCE_TYPES.map((type) => ({
|
||||
type,
|
||||
index: pathSegments.lastIndexOf(type),
|
||||
}))
|
||||
.filter(({ index }) => index !== -1)
|
||||
.sort((a, b) => b.index - a.index)
|
||||
.shift();
|
||||
|
||||
if (!foundResource) {
|
||||
throw new OperationalError('Unable to determine the resource type from the URL');
|
||||
}
|
||||
|
||||
const { type, index } = foundResource;
|
||||
const resourceId =
|
||||
pathSegments[index + 1] !== undefined
|
||||
? `${pathSegments.slice(0, index).join('/')}/${type}/${pathSegments[index + 1]}`
|
||||
: pathSegments.slice(0, index).join('/');
|
||||
|
||||
const key = Buffer.from(credentials.key as string, 'base64');
|
||||
const payload = `${(requestOptions.method ?? 'GET').toLowerCase()}\n${type.toLowerCase()}\n${resourceId}\n${date.toLowerCase()}\n\n`;
|
||||
const hmacSha256 = createHmac('sha256', key);
|
||||
const signature = hmacSha256.update(payload, 'utf8').digest('base64');
|
||||
|
||||
requestOptions.headers[HeaderConstants.AUTHORIZATION] = encodeURIComponent(
|
||||
`type=master&ver=1.0&sig=${signature}`,
|
||||
);
|
||||
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
test: ICredentialTestRequest = {
|
||||
request: {
|
||||
baseURL:
|
||||
'=https://{{ $credentials.account }}.documents.azure.com/dbs/{{ $credentials.database }}',
|
||||
url: '/colls',
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user