Token导航 LogoToken导航TokenDH.com
研究检索敏感数据github未标认证来源可访问许可证需确认审计提醒

node-add-oauthnode ADD OAuth 搜索

Agent Skill

用于辅助安全审计、权限检查、凭据风险、认证流程和常见漏洞排查。它适合让 Agent 梳理敏感配置、检查依赖风险、分析鉴权逻辑或生成安全复核清单。使用时不能把工具输出直接当最终结论,涉及密钥、令牌、用户数据或生产系统时,应先确认最小权限、脱敏方式和操作边界。

总安装

1,440

周安装

60

GitHub Stars

186,135

下载量

480
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:node-add-oauth(node ADD OAuth 搜索)
来源仓库:https://github.com/n8n-io/n8n
仓库路径:skills/node-add-oauth
安装命令:
npx skills add https://github.com/n8n-io/n8n --skill node-add-oauth
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/n8n-io/n8n --skill node-add-oauth

简介

node-add-oauth 用于辅助安全审计、权限检查和认证流程分析,支持凭据风险排查。

  • 适用于梳理敏感配置、检查依赖风险或生成安全复核清单。
  • 通过 npx skills add 命令从指定 GitHub 仓库安装并使用。
  • 使用时不能将工具输出直接作为结论,涉及密钥或生产系统时应先确认最小权限和操作边界。
  • 适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

SKILL.md

Overview

Add OAuth2 (Authorization Code / 3LO) support to an existing n8n node. Works for any third-party service that supports standard OAuth2.

Before starting, read comparable existing OAuth2 credential files and tests under packages/nodes-base/credentials/ to understand the conventions used in this codebase (e.g. DiscordOAuth2Api.credentials.ts, MicrosoftTeamsOAuth2Api.credentials.ts).


Step 0 — Parse arguments

Extract:

  • NODE_NAME: the service name (e.g. GitHub, Notion). Try to infer from the argument; if ambiguous, ask the user.
  • CUSTOM_SCOPES: whether the credential should support user-defined scopes. If the argument does not make this clear, ask the user before proceeding: "Should users be able to customise the OAuth2 scopes for this credential, or should scopes be fixed?"

Step 1 — Explore the node

Read the following (adjust path conventions for the specific service):

  1. Node directory: packages/nodes-base/nodes/{NODE_NAME}/

- Find *.node.ts (main node) and any *Trigger.node.ts - Find GenericFunctions.ts (may be named differently) - Check if an auth / version subdirectory exists

  1. Existing credentials: packages/nodes-base/credentials/ — look for existing {NODE_NAME}*Api.credentials.ts files to understand the naming convention and any auth method already in use.
  2. package.json at packages/nodes-base/package.json — find where existing credentials for this node are registered (grep for the node name).

Step 2 — Research OAuth2 endpoints

Look up the service's OAuth2 documentation:

  • Authorization URL
  • Access Token URL
  • Required auth query parameters (e.g. prompt=consent, access_type=offline)
  • Default scopes needed for the node's existing operations
  • Whether the API requires a cloudId / workspace ID lookup after the token exchange (Atlassian-style gateway APIs do; most services don't)

If you can't determine the endpoints confidently, ask the user to provide them.


Step 3 — Create the credential file

File: packages/nodes-base/credentials/{NODE_NAME}OAuth2Api.credentials.ts

import type { ICredentialType, INodeProperties } from 'n8n-workflow';

const defaultScopes = [/* minimum scopes for existing node operations */];

export class {NODE_NAME}OAuth2Api implements ICredentialType {
	name = '{camelCase}OAuth2Api';
	extends = ['oAuth2Api'];
	displayName = '{Display Name} OAuth2 API';
	documentationUrl = '{doc-slug}'; // matches docs.n8n.io/integrations/...

	properties: INodeProperties[] = [
		// Include service-specific fields the node needs to construct API calls
		// (e.g. domain, workspace URL) — add BEFORE the hidden fields below.

		{ displayName: 'Grant Type',        name: 'grantType',      type: 'hidden', default: 'authorizationCode' },
		{ displayName: 'Authorization URL', name: 'authUrl',        type: 'hidden', default: '{AUTH_URL}', required: true },
		{ displayName: 'Access Token URL',  name: 'accessTokenUrl', type: 'hidden', default: '{TOKEN_URL}', required: true },
		// Only include authQueryParameters if the service requires extra query params:
		{ displayName: 'Auth URI Query Parameters', name: 'authQueryParameters', type: 'hidden', default: '{QUERY_PARAMS}' },
		{ displayName: 'Authentication',    name: 'authentication', type: 'hidden', default: 'header' },

		// ── Custom scopes block (ONLY when CUSTOM_SCOPES = yes) ──────────────
		{
			displayName: 'Custom Scopes',
			name: 'customScopes',
			type: 'boolean',
			default: false,
			description: 'Define custom scopes',
		},
		{
			displayName:
				'The default scopes needed for the node to work are already set. If you change these the node may not function correctly.',
			name: 'customScopesNotice',
			type: 'notice',
			default: '',
			displayOptions: { show: { customScopes: [true] } },
		},
		{
			displayName: 'Enabled Scopes',
			name: 'enabledScopes',
			type: 'string',
			displayOptions: { show: { customScopes: [true] } },
			default: defaultScopes.join(' '),
			description: 'Scopes that should be enabled',
		},
		// ── End custom scopes block ───────────────────────────────────────────

		{
			displayName: 'Scope',
			name: 'scope',
			type: 'hidden',
			// Custom scopes: expression toggles between user value and defaults.
			// Fixed scopes: use the literal defaultScopes string instead.
			default:
				'={{$self["customScopes"] ? $self["enabledScopes"] : "' + defaultScopes.join(' ') + '"}}',
		},
	];
}

Rules:

  • No authenticate block — oAuth2Api machinery handles Bearer token injection automatically.
  • No test block — the OAuth dance validates the credential.
  • defaultScopes at module level is the single source of truth: it populates both the enabledScopes default and the scope expression fallback. Update it in one place.
  • If the service needs a domain / workspace URL for API call construction, add it as a visible string field before the hidden fields.

Step 4 — Register the credential in package.json

File: packages/nodes-base/package.json

Find the n8n.credentials array and insert the new entry near other credentials for this service (alphabetical ordering within the service's block):

"dist/credentials/{NODE_NAME}OAuth2Api.credentials.js",

Step 5 — Update GENERIC_OAUTH2_CREDENTIALS_WITH_EDITABLE_SCOPE (custom scopes only)

Only do this step when CUSTOM_SCOPES = yes.

File: packages/cli/src/constants.ts

Add '{camelCase}OAuth2Api' to the GENERIC_OAUTH2_CREDENTIALS_WITH_EDITABLE_SCOPE array. Without this, n8n deletes the user's custom scope on OAuth2 reconnect.

export const GENERIC_OAUTH2_CREDENTIALS_WITH_EDITABLE_SCOPE = [
	'oAuth2Api',
	'googleOAuth2Api',
	'microsoftOAuth2Api',
	'highLevelOAuth2Api',
	'mcpOAuth2Api',
	'{camelCase}OAuth2Api', // ← add this
];

Step 6 — Update GenericFunctions.ts

6a — Standard services (token works directly against the instance URL)

Add an else if branch before the existing else fallback:

} else if ({versionParam} === '{camelCase}OAuth2') {
	domain = (await this.getCredentials('{camelCase}OAuth2Api')).{domainField} as string;
	credentialType = '{camelCase}OAuth2Api';
} else {

6b — Gateway services requiring a workspace/cloud ID lookup

When the OAuth token is scoped for a gateway URL rather than the direct instance URL (Atlassian's api.atlassian.com is the canonical example), add a module-level cache and lookup helper before the main request function:

// Module-level cache: normalised domain → site/cloud ID
export const _cloudIdCache = new Map<string, string>();

async function getSiteId(
	this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions,
	credentialType: string,
	domain: string,
): Promise<string> {
	const normalizedDomain = domain.replace(/\/$/, '');
	if (_cloudIdCache.has(normalizedDomain)) return _cloudIdCache.get(normalizedDomain)!;

	const resources = (await this.helpers.requestWithAuthentication.call(this, credentialType, {
		uri: '{ACCESSIBLE_RESOURCES_ENDPOINT}',
		json: true,
	})) as Array<{ id: string; url: string }>;

	const site = resources.find((r) => r.url === normalizedDomain);
	if (!site) {
		throw new NodeOperationError(
			this.getNode(),
			`No accessible site found for domain: ${domain}. Make sure the domain matches your site URL exactly.`,
		);
	}

	_cloudIdCache.set(normalizedDomain, site.id);
	return site.id;
}

Then in the main request function:

} else if ({versionParam} === '{camelCase}OAuth2') {
	const rawDomain = (await this.getCredentials('{camelCase}OAuth2Api')).domain as string;
	credentialType = '{camelCase}OAuth2Api';
	const siteId = await getSiteId.call(this, credentialType, rawDomain);
	domain = `{GATEWAY_BASE_URL}/${siteId}`;
} else {

The existing uri: \${domain}/rest${endpoint}`` construction then produces the correct gateway URL automatically.

Add NodeOperationError to the n8n-workflow import if not already present.


Step 7 — Update the node file(s)

Main node (*.node.ts)

Credentials array — add an entry for the new credential type:

{
	name: '{camelCase}OAuth2Api',
	required: true,
	displayOptions: { show: { {versionParam}: ['{camelCase}OAuth2'] } },
},

Version/auth options — add to the {versionParam} (or equivalent) options list:

{ name: '{Display Name} (OAuth2)', value: '{camelCase}OAuth2' },

Keep default unchanged — existing workflows must not be affected.

Trigger node (*Trigger.node.ts, if present)

Same two changes. Preserve any displayName label pattern already used by other credential entries in that trigger node's credentials array.


Step 8 — Write credential tests

File: packages/nodes-base/credentials/test/{NODE_NAME}OAuth2Api.credentials.test.ts

Use ClientOAuth2 from @n8n/client-oauth2 and nock for HTTP mocking. Follow the structure in MicrosoftTeamsOAuth2Api.credentials.test.ts.

Required test cases:

  1. Metadata — name, extends array, enabledScopes default, auth URL, token URL, authQueryParameters default (if applicable).
  2. Default scopes in authorization URI — call oauthClient.code.getUri(), assert each default scope is present.
  3. Token retrieval with default scopes — mock the token endpoint with nock, call oauthClient.code.getToken(...), assert token.data.scope contains each scope.
  4. Custom scopes in authorization URI *(skip when CUSTOM_SCOPES = no)*.
  5. Token retrieval with custom scopes *(skip when CUSTOM_SCOPES = no)*.
  6. Minimal / different scope set *(skip when CUSTOM_SCOPES = no)* — assert scopes not in the set are absent from both the URI and token response.

Lifecycle hooks required:

beforeAll(() => { nock.disableNetConnect(); });
afterAll(() => { nock.restore(); });
afterEach(() => { nock.cleanAll(); });

Step 9 — Update GenericFunctions.test.ts

In the credential-routing describe block:

  1. If a site-ID cache (_cloudIdCache) was added, import it and call _cloudIdCache.clear() (or equivalent) in afterEach.
  2. Add/update the OAuth2 routing test case:

- Simple routing: assert getCredentials was called with the correct credential name and requestWithAuthentication was called with the correct name and URI. - Gateway lookup: mock requestWithAuthentication to return the accessible-resources payload on the first call and {} on the second. Assert the first call targets the resources endpoint and the second call uses the gateway base URL with the site ID.


Step 10 — Verify

# From packages/nodes-base/
pnpm test credentials/test/{NODE_NAME}OAuth2Api.credentials.test.ts
pnpm test nodes/{NODE_NAME}/__test__/GenericFunctions.test.ts
pnpm typecheck
pnpm lint

# Only when constants.ts was changed:
pushd ../cli && pnpm typecheck && popd

Fix any type errors before finishing. Never skip pnpm typecheck.

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

33.09%
按下载量换算159

Claude

31.13%
按下载量换算149

Cursor

17.47%
按下载量换算84

Gemini CLI

10.63%
按下载量换算51

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

可疑

权限和风险

敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills