fa-mcp-sdk 0.2.120 → 0.2.125
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/fa-mcp.js +84 -24
- package/cli-template/config/_local.yaml +21 -1
- package/cli-template/config/custom-environment-variables.yaml +11 -1
- package/cli-template/config/default.yaml +11 -1
- package/cli-template/fa-mcp-sdk-spec.md +385 -2
- package/cli-template/package.json +72 -73
- package/cli-template/src/_examples/custom-basic-auth-example.ts +252 -0
- package/cli-template/src/_examples/multi-auth-examples.ts +333 -0
- package/cli-template/src/custom-resources.ts +1 -0
- package/cli-template/yarn.lock +6375 -0
- package/dist/core/_types_/TNtlm.d.ts +5 -0
- package/dist/core/_types_/TNtlm.d.ts.map +1 -0
- package/dist/core/_types_/TNtlm.js +2 -0
- package/dist/core/_types_/TNtlm.js.map +1 -0
- package/dist/core/_types_/config.d.ts +88 -0
- package/dist/core/_types_/config.d.ts.map +1 -0
- package/dist/core/_types_/config.js +2 -0
- package/dist/core/_types_/config.js.map +1 -0
- package/dist/core/_types_/types.d.ts +8 -0
- package/dist/core/_types_/types.d.ts.map +1 -1
- package/dist/core/{token/token-core.d.ts → auth/jwt-validation.d.ts} +2 -2
- package/dist/core/auth/jwt-validation.d.ts.map +1 -0
- package/dist/core/{token/token-core.js → auth/jwt-validation.js} +4 -4
- package/dist/core/auth/jwt-validation.js.map +1 -0
- package/dist/core/auth/middleware.d.ts +47 -0
- package/dist/core/auth/middleware.d.ts.map +1 -0
- package/dist/core/{token/token-auth.js → auth/middleware.js} +114 -2
- package/dist/core/auth/middleware.js.map +1 -0
- package/dist/core/auth/multi-auth.d.ts +27 -0
- package/dist/core/auth/multi-auth.d.ts.map +1 -0
- package/dist/core/auth/multi-auth.js +300 -0
- package/dist/core/auth/multi-auth.js.map +1 -0
- package/dist/core/auth/token-generator/html.d.ts.map +1 -0
- package/dist/core/{token/gen-token-app → auth/token-generator}/html.js +2 -2
- package/dist/core/auth/token-generator/html.js.map +1 -0
- package/dist/core/auth/token-generator/ntlm-auth-options.d.ts.map +1 -0
- package/dist/core/{token/gen-token-app → auth/token-generator}/ntlm-auth-options.js +1 -1
- package/dist/core/auth/token-generator/ntlm-auth-options.js.map +1 -0
- package/dist/core/auth/token-generator/ntlm-domain-config.d.ts.map +1 -0
- package/dist/core/auth/token-generator/ntlm-domain-config.js.map +1 -0
- package/dist/core/auth/token-generator/ntlm-integration.d.ts.map +1 -0
- package/dist/core/{token/gen-token-app → auth/token-generator}/ntlm-integration.js +4 -4
- package/dist/core/auth/token-generator/ntlm-integration.js.map +1 -0
- package/dist/core/auth/token-generator/ntlm-session-storage.d.ts.map +1 -0
- package/dist/core/{token/gen-token-app → auth/token-generator}/ntlm-session-storage.js +1 -1
- package/dist/core/auth/token-generator/ntlm-session-storage.js.map +1 -0
- package/dist/core/auth/token-generator/ntlm-templates.d.ts.map +1 -0
- package/dist/core/auth/token-generator/ntlm-templates.js.map +1 -0
- package/dist/core/{token/gen-token-app/gen-token-server.d.ts → auth/token-generator/server.d.ts} +1 -1
- package/dist/core/auth/token-generator/server.d.ts.map +1 -0
- package/dist/core/{token/gen-token-app/gen-token-server.js → auth/token-generator/server.js} +3 -3
- package/dist/core/auth/token-generator/server.js.map +1 -0
- package/dist/core/auth/types.d.ts +35 -0
- package/dist/core/auth/types.d.ts.map +1 -0
- package/dist/core/auth/types.js +14 -0
- package/dist/core/auth/types.js.map +1 -0
- package/dist/core/cache/cache.d.ts.map +1 -1
- package/dist/core/cache/cache.js +3 -2
- package/dist/core/cache/cache.js.map +1 -1
- package/dist/core/index.d.ts +5 -3
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +4 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/web/server-http.js +1 -1
- package/dist/core/web/server-http.js.map +1 -1
- package/package.json +4 -2
- package/dist/core/token/gen-token-app/gen-token-server.d.ts.map +0 -1
- package/dist/core/token/gen-token-app/gen-token-server.js.map +0 -1
- package/dist/core/token/gen-token-app/html.d.ts.map +0 -1
- package/dist/core/token/gen-token-app/html.js.map +0 -1
- package/dist/core/token/gen-token-app/ntlm-auth-options.d.ts.map +0 -1
- package/dist/core/token/gen-token-app/ntlm-auth-options.js.map +0 -1
- package/dist/core/token/gen-token-app/ntlm-domain-config.d.ts.map +0 -1
- package/dist/core/token/gen-token-app/ntlm-domain-config.js.map +0 -1
- package/dist/core/token/gen-token-app/ntlm-integration.d.ts.map +0 -1
- package/dist/core/token/gen-token-app/ntlm-integration.js.map +0 -1
- package/dist/core/token/gen-token-app/ntlm-session-storage.d.ts.map +0 -1
- package/dist/core/token/gen-token-app/ntlm-session-storage.js.map +0 -1
- package/dist/core/token/gen-token-app/ntlm-templates.d.ts.map +0 -1
- package/dist/core/token/gen-token-app/ntlm-templates.js.map +0 -1
- package/dist/core/token/i-token.d.ts +0 -13
- package/dist/core/token/i-token.d.ts.map +0 -1
- package/dist/core/token/i-token.js +0 -2
- package/dist/core/token/i-token.js.map +0 -1
- package/dist/core/token/token-auth.d.ts +0 -17
- package/dist/core/token/token-auth.d.ts.map +0 -1
- package/dist/core/token/token-auth.js.map +0 -1
- package/dist/core/token/token-core.d.ts.map +0 -1
- package/dist/core/token/token-core.js.map +0 -1
- /package/dist/core/{token/gen-token-app → auth/token-generator}/html.d.ts +0 -0
- /package/dist/core/{token/gen-token-app → auth/token-generator}/ntlm-auth-options.d.ts +0 -0
- /package/dist/core/{token/gen-token-app → auth/token-generator}/ntlm-domain-config.d.ts +0 -0
- /package/dist/core/{token/gen-token-app → auth/token-generator}/ntlm-domain-config.js +0 -0
- /package/dist/core/{token/gen-token-app → auth/token-generator}/ntlm-integration.d.ts +0 -0
- /package/dist/core/{token/gen-token-app → auth/token-generator}/ntlm-session-storage.d.ts +0 -0
- /package/dist/core/{token/gen-token-app → auth/token-generator}/ntlm-templates.d.ts +0 -0
- /package/dist/core/{token/gen-token-app → auth/token-generator}/ntlm-templates.js +0 -0
package/bin/fa-mcp.js
CHANGED
|
@@ -6,6 +6,7 @@ import { fileURLToPath } from 'url';
|
|
|
6
6
|
import readline from 'readline';
|
|
7
7
|
import { v4 as uuidv4 } from 'uuid';
|
|
8
8
|
import chalk from 'chalk';
|
|
9
|
+
import yaml from 'js-yaml';
|
|
9
10
|
|
|
10
11
|
const __filename = fileURLToPath(import.meta.url);
|
|
11
12
|
const __dirname = path.dirname(__filename);
|
|
@@ -71,6 +72,34 @@ const getAsk = () => {
|
|
|
71
72
|
};
|
|
72
73
|
};
|
|
73
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Parse configuration file (JSON or YAML)
|
|
77
|
+
* @param {string} filePath - Path to the configuration file
|
|
78
|
+
* @param {string} content - Content of the file
|
|
79
|
+
* @returns {object} Parsed configuration object
|
|
80
|
+
*/
|
|
81
|
+
const parseConfigFile = (filePath, content) => {
|
|
82
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
if (ext === '.json') {
|
|
86
|
+
return JSON.parse(content);
|
|
87
|
+
} else if (ext === '.yaml' || ext === '.yml') {
|
|
88
|
+
return yaml.load(content, { schema: yaml.DEFAULT_SCHEMA });
|
|
89
|
+
} else {
|
|
90
|
+
// Try to detect format by content
|
|
91
|
+
const trimmed = content.trim();
|
|
92
|
+
if (trimmed.startsWith('{') || trimmed.startsWith('[')) {
|
|
93
|
+
return JSON.parse(content);
|
|
94
|
+
} else {
|
|
95
|
+
return yaml.load(content, { schema: yaml.DEFAULT_SCHEMA });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
} catch (error) {
|
|
99
|
+
throw new Error(`Failed to parse configuration file ${filePath}: ${error.message}`);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
74
103
|
class MCPGenerator {
|
|
75
104
|
constructor () {
|
|
76
105
|
this.templateDir = path.join(__dirname, '..', 'cli-template');
|
|
@@ -166,6 +195,11 @@ class MCPGenerator {
|
|
|
166
195
|
defaultValue: '<envCode.prod>',
|
|
167
196
|
title: 'Production environment code for Consul service ID generation',
|
|
168
197
|
},
|
|
198
|
+
{
|
|
199
|
+
name: 'NODE_CONSUL_ENV',
|
|
200
|
+
defaultValue: '',
|
|
201
|
+
title: 'Affects how the Consul service ID is formed - as a product or development ID. Valid values: "" | "development" | "production"',
|
|
202
|
+
},
|
|
169
203
|
|
|
170
204
|
{
|
|
171
205
|
name: 'mcp.domain',
|
|
@@ -487,6 +521,18 @@ certificate's public and private keys`,
|
|
|
487
521
|
config[name] = String(enabled);
|
|
488
522
|
continue;
|
|
489
523
|
}
|
|
524
|
+
case 'NODE_CONSUL_ENV': {
|
|
525
|
+
if (currentValue === '') {
|
|
526
|
+
continue;
|
|
527
|
+
}
|
|
528
|
+
value = await ask.optional(title, name, defaultValue);
|
|
529
|
+
if (value === '' || value === 'development' || value === 'production') {
|
|
530
|
+
config[name] = value;
|
|
531
|
+
} else {
|
|
532
|
+
config[name] = '';
|
|
533
|
+
}
|
|
534
|
+
continue;
|
|
535
|
+
}
|
|
490
536
|
|
|
491
537
|
default:
|
|
492
538
|
value = await ask.optional(title, name, defaultValue);
|
|
@@ -534,17 +580,17 @@ certificate's public and private keys`,
|
|
|
534
580
|
|
|
535
581
|
async collectConfiguration () {
|
|
536
582
|
const config = {};
|
|
537
|
-
const configFile = process.argv.find((arg) => arg.endsWith('.json')) ||
|
|
583
|
+
const configFile = process.argv.find((arg) => arg.endsWith('.json') || arg.endsWith('.yaml') || arg.endsWith('.yml')) ||
|
|
538
584
|
process.argv.find((arg) => arg.startsWith('--config='))?.split('=')[1];
|
|
539
585
|
|
|
540
586
|
if (configFile) {
|
|
541
587
|
try {
|
|
542
588
|
const configData = await fs.readFile(configFile, 'utf8');
|
|
543
|
-
const parsedConfig =
|
|
589
|
+
const parsedConfig = parseConfigFile(configFile, configData);
|
|
544
590
|
Object.assign(config, parsedConfig);
|
|
545
591
|
console.log(`📋 Loaded configuration from: ${hly(configFile)}`);
|
|
546
592
|
} catch (error) {
|
|
547
|
-
console.warn(`⚠️ Warning: Could not load config file ${configFile}`);
|
|
593
|
+
console.warn(`⚠️ Warning: Could not load config file ${configFile}: ${error.message}`);
|
|
548
594
|
}
|
|
549
595
|
}
|
|
550
596
|
|
|
@@ -565,7 +611,9 @@ certificate's public and private keys`,
|
|
|
565
611
|
} else if (configProxy.NODE_ENV === 'production') {
|
|
566
612
|
configProxy.isProduction = 'true';
|
|
567
613
|
}
|
|
568
|
-
|
|
614
|
+
if (config['logger.useFileLogger'] !== 'true') {
|
|
615
|
+
config['logger.dir'] = '';
|
|
616
|
+
}
|
|
569
617
|
let confirmed = false;
|
|
570
618
|
let isRetry = false;
|
|
571
619
|
|
|
@@ -592,34 +640,34 @@ certificate's public and private keys`,
|
|
|
592
640
|
async getTargetPath (config = {}) {
|
|
593
641
|
const ask = getAsk();
|
|
594
642
|
|
|
595
|
-
let
|
|
643
|
+
let tp = process.cwd();
|
|
596
644
|
let createInCurrent;
|
|
597
645
|
let pPath = trim(config.projectAbsPath);
|
|
598
646
|
if (pPath) {
|
|
599
|
-
|
|
600
|
-
console.log(`Create project in: ${hl(
|
|
647
|
+
tp = path.resolve(pPath);
|
|
648
|
+
console.log(`Create project in: ${hl(tp)}${FROM_CONFIG}`);
|
|
601
649
|
} else {
|
|
602
|
-
createInCurrent = await ask.yn(`Create project in current directory? (${hl(
|
|
650
|
+
createInCurrent = await ask.yn(`Create project in current directory? (${hl(tp)})`, '', 'n');
|
|
603
651
|
if (!createInCurrent) {
|
|
604
|
-
|
|
605
|
-
|
|
652
|
+
tp = await ask.question('Enter absolute path for project: ');
|
|
653
|
+
tp = path.resolve(tp);
|
|
606
654
|
}
|
|
607
655
|
}
|
|
608
656
|
|
|
609
|
-
config.projectAbsPath =
|
|
657
|
+
config.projectAbsPath = tp;
|
|
610
658
|
// Create directory if it doesn't exist
|
|
611
659
|
try {
|
|
612
|
-
await fs.access(
|
|
660
|
+
await fs.access(tp);
|
|
613
661
|
} catch {
|
|
614
662
|
console.log('Creating directory recursively...');
|
|
615
|
-
await fs.mkdir(
|
|
663
|
+
await fs.mkdir(tp, { recursive: true });
|
|
616
664
|
}
|
|
617
665
|
|
|
618
|
-
const errMsg = `❌ Directory ${hl(
|
|
666
|
+
const errMsg = `❌ Directory ${hl(tp)} not empty - cannot create project here. Use an empty directory or specify a different path.`;
|
|
619
667
|
|
|
620
668
|
// Check if directory is empty
|
|
621
669
|
try {
|
|
622
|
-
const files = await fs.readdir(
|
|
670
|
+
const files = await fs.readdir(tp);
|
|
623
671
|
const allowedFiles = [
|
|
624
672
|
'.git',
|
|
625
673
|
'.idea',
|
|
@@ -650,7 +698,7 @@ certificate's public and private keys`,
|
|
|
650
698
|
}
|
|
651
699
|
|
|
652
700
|
ask.close();
|
|
653
|
-
return
|
|
701
|
+
return tp;
|
|
654
702
|
}
|
|
655
703
|
|
|
656
704
|
async copyDirectory (source, target) {
|
|
@@ -675,6 +723,7 @@ certificate's public and private keys`,
|
|
|
675
723
|
|
|
676
724
|
async handlePackageJson (content, config) {
|
|
677
725
|
try {
|
|
726
|
+
content = content.replace('"project.name"', '"{{project.name}}"');
|
|
678
727
|
// First replace all template parameters in the content string
|
|
679
728
|
let updatedContent = content;
|
|
680
729
|
for (const [param, value] of Object.entries(config)) {
|
|
@@ -728,7 +777,16 @@ certificate's public and private keys`,
|
|
|
728
777
|
return files;
|
|
729
778
|
}
|
|
730
779
|
|
|
731
|
-
async
|
|
780
|
+
async transformTargetFile (config, targetRelPath, transformFn) {
|
|
781
|
+
const targetPath = config.projectAbsPath;
|
|
782
|
+
const targetFullPath = path.join(targetPath, targetRelPath);
|
|
783
|
+
const content = await fs.readFile(targetFullPath, 'utf8');
|
|
784
|
+
const transformedContent = transformFn(content, config);
|
|
785
|
+
await fs.writeFile(targetFullPath, transformedContent, 'utf8');
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
async replaceTemplateParameters (config) {
|
|
789
|
+
const targetPath = config.projectAbsPath;
|
|
732
790
|
const files = await this.getAllFiles(targetPath);
|
|
733
791
|
|
|
734
792
|
for (const filePath of files) {
|
|
@@ -754,10 +812,11 @@ certificate's public and private keys`,
|
|
|
754
812
|
await fs.writeFile(filePath, content, 'utf8');
|
|
755
813
|
}
|
|
756
814
|
}
|
|
815
|
+
if (config['NODE_CONSUL_ENV'] === '') {
|
|
816
|
+
await this.transformTargetFile(config, '.env', (c) => c.replace(/^(NODE_CONSUL_ENV)=([^\r\n]*)/m, '#$1=$2'));
|
|
817
|
+
}
|
|
757
818
|
if (config['claude.isBypassPermissions'] === 'true') {
|
|
758
|
-
const
|
|
759
|
-
const content = await fs.readFile(settingsPath, 'utf8')
|
|
760
|
-
.replace('"acceptEdits"', '"bypassPermissions"')
|
|
819
|
+
const transformFn = (c) => c.replace('"acceptEdits"', '"bypassPermissions"')
|
|
761
820
|
.replace(/"allow": \[\s+"Edit",/, `"allow": [
|
|
762
821
|
"Bash(sudo cp:*)",
|
|
763
822
|
"Bash(sudo:*)",
|
|
@@ -791,11 +850,12 @@ certificate's public and private keys`,
|
|
|
791
850
|
"Bash(unset http_proxy)",
|
|
792
851
|
"Bash(wc:*)",
|
|
793
852
|
"Edit",`);
|
|
794
|
-
await
|
|
853
|
+
await this.transformTargetFile(config, '.claude/settings.json', transformFn);
|
|
795
854
|
}
|
|
796
855
|
}
|
|
797
856
|
|
|
798
|
-
async createProject (
|
|
857
|
+
async createProject (config) {
|
|
858
|
+
const targetPath = config.projectAbsPath;
|
|
799
859
|
// Copy template files
|
|
800
860
|
await this.copyDirectory(this.templateDir, targetPath);
|
|
801
861
|
await fs.copyFile(path.join(targetPath, '.env.example'), path.join(targetPath, '.env')); // VVT
|
|
@@ -829,7 +889,7 @@ certificate's public and private keys`,
|
|
|
829
889
|
}
|
|
830
890
|
|
|
831
891
|
// Replace template parameters
|
|
832
|
-
await this.replaceTemplateParameters(
|
|
892
|
+
await this.replaceTemplateParameters(config);
|
|
833
893
|
|
|
834
894
|
// Replace template placeholders with defaultValue from optionalParams and save as _local.yaml
|
|
835
895
|
if (localYamlContent) {
|
|
@@ -878,7 +938,7 @@ certificate's public and private keys`,
|
|
|
878
938
|
const targetPath = await this.getTargetPath(config);
|
|
879
939
|
|
|
880
940
|
console.log(`\n📁 Creating project in: ${targetPath}`);
|
|
881
|
-
await this.createProject(
|
|
941
|
+
await this.createProject(config);
|
|
882
942
|
|
|
883
943
|
console.log('\n✅ MCP Server template created successfully!');
|
|
884
944
|
console.log('\n📋 Next steps:');
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
# Copy this file to local.yaml and update with your database credentials
|
|
2
2
|
# local.yaml is gitignored and won't be committed
|
|
3
3
|
---
|
|
4
|
+
#ad:
|
|
5
|
+
# domains:
|
|
6
|
+
# MYDOMAIN:
|
|
7
|
+
# default: true
|
|
8
|
+
# controllers:
|
|
9
|
+
# - 'ldap://c1.corp.com'
|
|
10
|
+
# - 'ldap://c2.corp.com'
|
|
11
|
+
# username: '***'
|
|
12
|
+
# password: '***'
|
|
13
|
+
|
|
4
14
|
# --------------------------------------------------
|
|
5
15
|
# CACHING Reduces API calls by caching responses
|
|
6
16
|
# --------------------------------------------------
|
|
@@ -69,8 +79,18 @@ webServer:
|
|
|
69
79
|
enabled: {{webServer.auth.enabled}} # Enables/disables token authorization
|
|
70
80
|
# An array of fixed tokens that pass to the MCP (use only for MCPs with green data or for development)
|
|
71
81
|
permanentServerTokens: []
|
|
72
|
-
|
|
82
|
+
jwtToken:
|
|
73
83
|
# Symmetric encryption key to generate a token for this MCP
|
|
74
84
|
encryptKey: '{{webServer.auth.token.encryptKey}}'
|
|
75
85
|
# If webServer.auth.enabled and the parameter true, the service name and the service specified in the token will be checked
|
|
76
86
|
checkMCPName: {{webServer.auth.token.checkMCPName}}
|
|
87
|
+
#basic:
|
|
88
|
+
# username: '***'
|
|
89
|
+
# password: '***'
|
|
90
|
+
#oauth2:
|
|
91
|
+
# type: 'oauth2';
|
|
92
|
+
# clientId: '***'
|
|
93
|
+
# clientSecret: '***'
|
|
94
|
+
# redirectUri?: 'string'
|
|
95
|
+
# tokenEndpoint?: string # For custom OAuth providers // VVR
|
|
96
|
+
#pat: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
cache:
|
|
2
2
|
ttlSeconds: CACHE_TTL_SECONDS
|
|
3
3
|
maxItems: CACHE_MAX_ITEMS
|
|
4
|
+
checkPeriod: CACHE_CHECK_PERIOD
|
|
4
5
|
|
|
5
6
|
db:
|
|
6
7
|
postgres:
|
|
@@ -33,6 +34,15 @@ webServer:
|
|
|
33
34
|
auth:
|
|
34
35
|
enabled: WS_AUTH_ENABLED
|
|
35
36
|
permanentServerTokens: WS_SERVER_TOKENS # comma separated list
|
|
36
|
-
|
|
37
|
+
jwtToken:
|
|
37
38
|
encryptKey: WS_TOKEN_ENCRYPT_KEY
|
|
38
39
|
checkMCPName: WS_CHECK_MC_NAME
|
|
40
|
+
basic:
|
|
41
|
+
username: WS_AUTH_BASIC_USERNAME
|
|
42
|
+
password: WS_AUTH_BASIC_PASSWORD
|
|
43
|
+
oauth2:
|
|
44
|
+
clientId: WS_AUTH_OAUTH2_CLIENT_ID
|
|
45
|
+
clientSecret: WS_AUTH_OAUTH2_CLIENT_SECRET
|
|
46
|
+
redirectUri: WS_AUTH_OAUTH2_REDIRECT_URI
|
|
47
|
+
tokenEndpoint: WS_AUTH_OAUTH2_TOKEN_ENDPOINT # For custom OAuth providers // VVR
|
|
48
|
+
pat: WS_AUTH_PAT
|
|
@@ -114,8 +114,18 @@ webServer:
|
|
|
114
114
|
enabled: false # Enables/disables token authorization
|
|
115
115
|
# An array of fixed tokens that pass to the MCP (use only for MCPs with green data or for development)
|
|
116
116
|
permanentServerTokens: []
|
|
117
|
-
|
|
117
|
+
jwtToken:
|
|
118
118
|
# Symmetric encryption key to generate a token for this MCP
|
|
119
119
|
encryptKey: '***'
|
|
120
120
|
# If webServer.auth.enabled and the parameter true, the service name and the service specified in the token will be checked
|
|
121
121
|
checkMCPName: true
|
|
122
|
+
#basic:
|
|
123
|
+
# username: '***'
|
|
124
|
+
# password: '***'
|
|
125
|
+
#oauth2:
|
|
126
|
+
# type: 'oauth2';
|
|
127
|
+
# clientId: '***'
|
|
128
|
+
# clientSecret: '***'
|
|
129
|
+
# redirectUri?: 'string'
|
|
130
|
+
# tokenEndpoint?: string # For custom OAuth providers // VVR
|
|
131
|
+
#pat: string;
|