neutrinos-cli 1.0.2 → 2.0.0-beta.0
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 → dist/src/bin}/cli.js +117 -125
- package/{cli-auth → dist/src/cli-auth}/auth.js +3 -24
- package/{cli-auth → dist/src/cli-auth}/server.js +6 -15
- package/{cli-auth → dist/src/cli-auth}/services/auth-utils.js +5 -24
- package/{commands → dist/src/commands}/attribute.js +36 -43
- package/{commands → dist/src/commands}/build.js +10 -25
- package/dist/src/commands/completion.js +298 -0
- package/dist/src/commands/deprecate.js +62 -0
- package/{commands → dist/src/commands}/dev.js +1 -12
- package/dist/src/commands/generate.js +10 -0
- package/{commands → dist/src/commands}/new-workspace.js +24 -50
- package/{commands → dist/src/commands}/publish.js +53 -200
- package/dist/src/commands/select-packages.js +22 -0
- package/{commands → dist/src/commands}/serve.js +7 -8
- package/dist/src/types/alpha-package.js +1 -0
- package/dist/src/types/marketplace.js +1 -0
- package/dist/src/types/session.js +1 -0
- package/dist/src/types/workspace.js +1 -0
- package/{utils → dist/src/utils}/attribute-utils.js +67 -44
- package/{utils → dist/src/utils}/check-valid-ws.js +1 -2
- package/{utils → dist/src/utils}/copy-utils.js +16 -28
- package/{utils → dist/src/utils}/create-client.js +3 -7
- package/{utils → dist/src/utils}/file-utils.js +10 -14
- package/{utils → dist/src/utils}/generate-component.js +10 -22
- package/{utils → dist/src/utils}/generate-module.js +4 -7
- package/dist/src/utils/get-package-info.js +60 -0
- package/dist/src/utils/get-packages.js +11 -0
- package/{utils → dist/src/utils}/inquirer-utils.js +8 -36
- package/dist/src/utils/logger.js +11 -0
- package/dist/src/utils/marketplace-api-utils.js +16 -0
- package/dist/src/utils/path-utils.js +28 -0
- package/dist/src/utils/prettify.js +15 -0
- package/{utils/user-seesion-utils.js → dist/src/utils/user-session-utils.js} +6 -9
- package/package.json +23 -21
- package/templates/module/.module.js.hbs +2 -2
- package/cli-auth/publish.js +0 -7
- package/commands/alpha-publish.js +0 -239
- package/commands/deprecate.js +0 -88
- package/commands/generate.js +0 -19
- package/commands/select-packages.mjs +0 -36
- package/templates/project/Dockerfile +0 -15
- package/templates/project/helmchart/.helmignore +0 -23
- package/templates/project/helmchart/Chart.yaml +0 -24
- package/templates/project/helmchart/templates/NOTES.txt +0 -22
- package/templates/project/helmchart/templates/_helpers.tpl +0 -62
- package/templates/project/helmchart/templates/deployment.yaml +0 -69
- package/templates/project/helmchart/templates/ingress.yaml +0 -62
- package/templates/project/helmchart/templates/service.yaml +0 -14
- package/templates/project/helmchart/values.yaml +0 -74
- package/utils/get-package-info.js +0 -53
- package/utils/get-packages.js +0 -15
- package/utils/logger.js +0 -35
- package/utils/marketplace-api-utils.js +0 -34
- package/utils/path-utils.js +0 -40
- package/utils/prettify.js +0 -36
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
const [major] = process.versions.node.split('.').map(Number);
|
|
3
|
+
if (major < 22) {
|
|
4
|
+
console.error('neutrinos requires Node.js 22+. Current: ' + process.version);
|
|
5
|
+
process.exit(1);
|
|
6
|
+
}
|
|
4
7
|
import dotenv from 'dotenv';
|
|
8
|
+
import { PACKAGE_ROOT } from '../utils/path-utils.js';
|
|
5
9
|
dotenv.config({
|
|
6
|
-
path: join(
|
|
10
|
+
path: join(PACKAGE_ROOT, '.env'),
|
|
7
11
|
});
|
|
8
|
-
////////////////////////////////////
|
|
9
12
|
import { greenBright } from 'colorette';
|
|
10
|
-
import { Command,
|
|
13
|
+
import { Argument, Command, Option } from 'commander';
|
|
11
14
|
import EventEmitter from 'node:events';
|
|
12
15
|
import { cwd, env, exit } from 'node:process';
|
|
16
|
+
import { readFileSync, realpathSync } from 'node:fs';
|
|
13
17
|
import { fileURLToPath } from 'node:url';
|
|
14
18
|
import open from 'open';
|
|
15
|
-
import { join } from 'path';
|
|
19
|
+
import { join, resolve } from 'node:path';
|
|
16
20
|
import { init } from '../cli-auth/server.js';
|
|
17
|
-
import { publish as alphaPublish } from '../commands/alpha-publish.js';
|
|
18
21
|
import { addAttribute } from '../commands/attribute.js';
|
|
19
22
|
import { build } from '../commands/build.js';
|
|
20
23
|
import { deprecate } from '../commands/deprecate.js';
|
|
@@ -23,25 +26,25 @@ import { generate } from '../commands/generate.js';
|
|
|
23
26
|
import { createWorkspace } from '../commands/new-workspace.js';
|
|
24
27
|
import { publish } from '../commands/publish.js';
|
|
25
28
|
import { startPluginsServer } from '../commands/serve.js';
|
|
29
|
+
import { completion } from '../commands/completion.js';
|
|
30
|
+
import { getPackages } from '../utils/get-packages.js';
|
|
26
31
|
import { validateWorkspace } from '../utils/check-valid-ws.js';
|
|
27
32
|
import { done, failed, inprogress, log } from '../utils/logger.js';
|
|
28
33
|
import { authConfigJson } from '../utils/path-utils.js';
|
|
34
|
+
const { version: CLI_VERSION } = JSON.parse(readFileSync(join(PACKAGE_ROOT, 'package.json'), 'utf-8'));
|
|
29
35
|
export const createProgram = () => {
|
|
30
36
|
const program = new Command();
|
|
31
|
-
|
|
32
|
-
program.version('1.0.0', '-v, --version', 'Output the version number');
|
|
33
|
-
|
|
37
|
+
program.version(CLI_VERSION, '-v, --version', 'Output the version number');
|
|
34
38
|
program
|
|
35
39
|
.command('new <name>')
|
|
36
40
|
.description('Create a new project')
|
|
37
41
|
.action((name) => {
|
|
38
|
-
|
|
39
|
-
|
|
42
|
+
createWorkspace(join(cwd(), name), name);
|
|
43
|
+
});
|
|
40
44
|
const generateCmd = program
|
|
41
45
|
.command('generate')
|
|
42
46
|
.alias('g')
|
|
43
47
|
.description('Generate a new plugin. Run "help generate" for more information.');
|
|
44
|
-
|
|
45
48
|
generateCmd
|
|
46
49
|
.command('component')
|
|
47
50
|
.alias('c')
|
|
@@ -49,12 +52,12 @@ export const createProgram = () => {
|
|
|
49
52
|
.option('-d,--description <description>', 'Description of the package')
|
|
50
53
|
.description('Generate a new component plugin')
|
|
51
54
|
.action(async (name, options) => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
});
|
|
55
|
+
await generate.component({
|
|
56
|
+
name,
|
|
57
|
+
dir: cwd(),
|
|
58
|
+
description: options.description,
|
|
57
59
|
});
|
|
60
|
+
});
|
|
58
61
|
generateCmd
|
|
59
62
|
.command('module')
|
|
60
63
|
.alias('m')
|
|
@@ -62,21 +65,18 @@ export const createProgram = () => {
|
|
|
62
65
|
.option('-d,--description <description>', 'Description of the package')
|
|
63
66
|
.description('Generate a new module plugin')
|
|
64
67
|
.action(async (name, options) => {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
});
|
|
68
|
+
await generate.module({
|
|
69
|
+
name,
|
|
70
|
+
dir: cwd(),
|
|
71
|
+
description: options.description,
|
|
70
72
|
});
|
|
73
|
+
});
|
|
71
74
|
generateCmd
|
|
72
75
|
.command('attribute')
|
|
73
76
|
.alias('a')
|
|
74
77
|
.argument('[componentName]', 'Component name')
|
|
75
78
|
.option('-t , --type <attributeType>', 'Type of attribute can be property, event, validation')
|
|
76
|
-
.option(
|
|
77
|
-
'-u , --ui-type <uiType>',
|
|
78
|
-
'Ui-type of attribute can be ===> input, toggle, dropdown, multi-select, typed-input, range, color-picker, data-source, data-set, table-actions, data-mapping',
|
|
79
|
-
)
|
|
79
|
+
.option('-u , --ui-type <uiType>', 'Ui-type of attribute can be ===> input, toggle, dropdown, multi-select, typed-input, range, color-picker, data-source, data-set, table-actions, data-mapping')
|
|
80
80
|
.option('-l , --label <label>', 'Label for an attribute')
|
|
81
81
|
.option('-e , --event <event>', 'Event name for an attribute if -t/--type is event')
|
|
82
82
|
.option('-c , --category <category>', 'Category for an attribute')
|
|
@@ -87,86 +87,63 @@ export const createProgram = () => {
|
|
|
87
87
|
.option('-n , --validation <validation>', 'Validation for an attribute')
|
|
88
88
|
.description('Generate an Attribute for component')
|
|
89
89
|
.action(async (componentName, options) => {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
return await addAttribute(componentName, cwd(), options);
|
|
91
|
+
});
|
|
93
92
|
const authCommand = program.command('auth').description('perform: login, logout, or status');
|
|
94
93
|
authCommand
|
|
95
94
|
.command('login')
|
|
96
95
|
.description('authenticate with the server')
|
|
97
|
-
.action((
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
});
|
|
128
|
-
await cliServer.start(eventEmitter);
|
|
129
|
-
const url = `http://localhost:${env.PORT}/login`;
|
|
130
|
-
inprogress(`open to login ${greenBright(url)}`);
|
|
131
|
-
await open(url);
|
|
96
|
+
.action(() => {
|
|
97
|
+
return new Promise(async (resolve, reject) => {
|
|
98
|
+
inprogress('logging in...');
|
|
99
|
+
const cliServer = await init({
|
|
100
|
+
tokenSetPath: authConfigJson(),
|
|
101
|
+
});
|
|
102
|
+
if (!cliServer) {
|
|
103
|
+
failed('Issuer not found');
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const eventEmitter = new EventEmitter();
|
|
107
|
+
eventEmitter.on('cli-auth:login', () => {
|
|
108
|
+
done('login successful');
|
|
109
|
+
resolve();
|
|
110
|
+
process.exit(0);
|
|
111
|
+
});
|
|
112
|
+
eventEmitter.on('cli-auth:login-failed', () => {
|
|
113
|
+
failed('login failed');
|
|
114
|
+
reject();
|
|
115
|
+
process.exit(1);
|
|
116
|
+
});
|
|
117
|
+
process.on('SIGINT', () => {
|
|
118
|
+
failed('exiting unexpectedly');
|
|
119
|
+
void cliServer.stop();
|
|
120
|
+
exit(0);
|
|
121
|
+
});
|
|
122
|
+
process.on('SIGTERM', () => {
|
|
123
|
+
failed('exiting unexpectedly');
|
|
124
|
+
void cliServer.stop();
|
|
125
|
+
exit(0);
|
|
132
126
|
});
|
|
127
|
+
await cliServer.start(eventEmitter);
|
|
128
|
+
const url = `http://localhost:${env.PORT}/login`;
|
|
129
|
+
inprogress(`open to login ${greenBright(url)}`);
|
|
130
|
+
await open(url);
|
|
133
131
|
});
|
|
132
|
+
});
|
|
134
133
|
authCommand
|
|
135
134
|
.command('state')
|
|
136
135
|
.description('get the current state of auth')
|
|
137
136
|
.action(() => {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
137
|
+
console.log('state');
|
|
138
|
+
});
|
|
141
139
|
program
|
|
142
140
|
.command('publish')
|
|
143
141
|
.argument('[packageName]', 'Component name')
|
|
144
|
-
.
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
.option('-i, --icon <iconPath>', 'Icon path')
|
|
150
|
-
.option('-m, --images <imagePaths...>', 'Image paths')
|
|
151
|
-
.description('Bundle and publish the plugin')
|
|
152
|
-
.action(async (packageName, options) => {
|
|
153
|
-
if (
|
|
154
|
-
options.versionType &&
|
|
155
|
-
!['patch', 'minor', 'major'].includes((options.versionType || '').toLowerCase())
|
|
156
|
-
) {
|
|
157
|
-
failed('Invalid version type should be one of "patch", "minor", "major"');
|
|
158
|
-
exit(0);
|
|
159
|
-
}
|
|
160
|
-
return await publish(packageName, cwd(), options);
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
program
|
|
164
|
-
.command('alpha:publish')
|
|
165
|
-
.argument('[packageName]', 'Component name')
|
|
166
|
-
.option(
|
|
167
|
-
'-t, --version-type <versionType>',
|
|
168
|
-
'Version type for version up can be one of "patch", "minor", "major"',
|
|
169
|
-
)
|
|
142
|
+
.addOption(new Option('-t, --version-type <versionType>', 'Version type for version up').choices([
|
|
143
|
+
'patch',
|
|
144
|
+
'minor',
|
|
145
|
+
'major',
|
|
146
|
+
]))
|
|
170
147
|
.option('-d, --display-name <displayName>', 'Display Name for the package')
|
|
171
148
|
.option('-i, --icon <iconPath>', 'Icon path')
|
|
172
149
|
.option('-m, --images <imagePaths...>', 'Image paths')
|
|
@@ -174,56 +151,65 @@ export const createProgram = () => {
|
|
|
174
151
|
.option('--all', 'Select all the packages')
|
|
175
152
|
.description('Bundle and publish the plugin')
|
|
176
153
|
.action(async (packageName, options) => {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
!['patch', 'minor', 'major'].includes((options.versionType || '').toLowerCase())
|
|
180
|
-
) {
|
|
181
|
-
failed('Invalid version type should be one of "patch", "minor", "major"');
|
|
182
|
-
exit(0);
|
|
183
|
-
}
|
|
184
|
-
return await alphaPublish(packageName, cwd(), options);
|
|
185
|
-
});
|
|
186
|
-
|
|
154
|
+
return await publish(packageName, cwd(), options);
|
|
155
|
+
});
|
|
187
156
|
program
|
|
188
157
|
.command('deprecate')
|
|
189
158
|
.option('-y, --yes', 'Confirmation to deprecate a package')
|
|
190
159
|
.option('--all', 'Select all the packages')
|
|
191
160
|
.argument('[packageName]', 'Package name')
|
|
192
161
|
.action(async (packageName, options) => {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
162
|
+
return await deprecate(packageName, cwd(), options);
|
|
163
|
+
});
|
|
196
164
|
program
|
|
197
165
|
.command('build')
|
|
198
|
-
.
|
|
199
|
-
if (value !== 'plugins' && value !== 'docker') {
|
|
200
|
-
throw new InvalidArgumentError('"build" can be "plugins" or "docker"');
|
|
201
|
-
}
|
|
202
|
-
return value;
|
|
203
|
-
})
|
|
166
|
+
.addArgument(new Argument('<type>', 'Type of build').choices(['plugins', 'docker']))
|
|
204
167
|
.argument('[pluginName]', 'Name of the plugin')
|
|
205
168
|
.option('--module', 'Build the plugin as a module')
|
|
206
169
|
.option('--all', 'Build all the plugin of the workspace')
|
|
207
170
|
.description('Build the plugin')
|
|
208
171
|
.action((type, pluginName, options) => {
|
|
209
|
-
|
|
210
|
-
|
|
172
|
+
build[type](cwd(), pluginName ?? '', options ?? {});
|
|
173
|
+
});
|
|
211
174
|
program
|
|
212
175
|
.command('start')
|
|
213
176
|
.option('-p, --port <port>', 'Port number for serving the plugin')
|
|
214
177
|
.description('start the live server for the plugin')
|
|
215
178
|
.action((options) => {
|
|
216
|
-
|
|
217
|
-
|
|
179
|
+
servePlugin(cwd(), Number(options.port) || 6969);
|
|
180
|
+
});
|
|
218
181
|
program
|
|
219
182
|
.command('serve')
|
|
183
|
+
.option('-p, --port <port>', 'Port number for serving the plugins', '3000')
|
|
220
184
|
.description('Start the express server that serves the plugins')
|
|
185
|
+
.action((options) => {
|
|
186
|
+
startPluginsServer(cwd(), Number(options.port));
|
|
187
|
+
});
|
|
188
|
+
program
|
|
189
|
+
.command('completion')
|
|
190
|
+
.description('Output shell completion script')
|
|
191
|
+
.addArgument(new Argument('<shell>', 'Shell type').choices(['bash', 'zsh']))
|
|
192
|
+
.action((shell) => {
|
|
193
|
+
completion(program, shell);
|
|
194
|
+
});
|
|
195
|
+
program
|
|
196
|
+
.command('__list-packages', { hidden: true })
|
|
197
|
+
.description('List workspace package names (used by shell completion)')
|
|
221
198
|
.action(() => {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
199
|
+
try {
|
|
200
|
+
const packages = getPackages(cwd());
|
|
201
|
+
for (const p of packages) {
|
|
202
|
+
const pkgJson = JSON.parse(readFileSync(join(p, 'package.json'), 'utf-8'));
|
|
203
|
+
process.stdout.write(pkgJson.name + '\n');
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
// Silently fail — completion should never error
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
program.hook('preAction', async (_thisCmd, actionCmd) => {
|
|
225
211
|
const cmd = actionCmd.name();
|
|
226
|
-
if (cmd === 'new' || cmd === 'login') {
|
|
212
|
+
if (cmd === 'new' || cmd === 'login' || cmd === 'completion' || cmd === '__list-packages') {
|
|
227
213
|
return;
|
|
228
214
|
}
|
|
229
215
|
if (!validateWorkspace(cwd())) {
|
|
@@ -231,9 +217,15 @@ export const createProgram = () => {
|
|
|
231
217
|
exit(1);
|
|
232
218
|
}
|
|
233
219
|
});
|
|
234
|
-
|
|
235
220
|
return program;
|
|
236
221
|
};
|
|
237
|
-
|
|
238
|
-
const
|
|
239
|
-
|
|
222
|
+
// Only parse when run directly (not when imported for testing/introspection)
|
|
223
|
+
const self = realpathSync(fileURLToPath(import.meta.url));
|
|
224
|
+
const entry = process.argv[1] ? realpathSync(resolve(process.argv[1])) : '';
|
|
225
|
+
if (self === entry) {
|
|
226
|
+
const program = createProgram();
|
|
227
|
+
program.parseAsync(process.argv).catch((err) => {
|
|
228
|
+
failed(err.message || 'An unexpected error occurred');
|
|
229
|
+
exit(1);
|
|
230
|
+
});
|
|
231
|
+
}
|
|
@@ -1,46 +1,25 @@
|
|
|
1
|
-
import EventEmitter from 'node:events';
|
|
2
1
|
import { existsSync } from 'node:fs';
|
|
3
2
|
import { mkdir, writeFile } from 'node:fs/promises';
|
|
4
3
|
import { sep } from 'node:path';
|
|
5
4
|
import { authUtils } from './services/auth-utils.js';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @param {import('openid-client').Client} client
|
|
9
|
-
* @param {string} tokenSetPath
|
|
10
|
-
*/
|
|
11
5
|
export const auth = (client, tokenSetPath) => {
|
|
12
6
|
const authStateNonce = {
|
|
13
7
|
state: '',
|
|
14
8
|
nonce: '',
|
|
15
9
|
};
|
|
16
|
-
/**
|
|
17
|
-
*
|
|
18
|
-
* @param {import('fastify').FastifyRequest} req
|
|
19
|
-
* @param {import('fastify').FastifyReply} reply
|
|
20
|
-
*/
|
|
21
10
|
return {
|
|
22
|
-
/**
|
|
23
|
-
* @param {import('fastify').FastifyInstance} server
|
|
24
|
-
* @param {EventEmitter} eventEmitter
|
|
25
|
-
*/
|
|
26
11
|
mount: (server, eventEmitter) => {
|
|
27
|
-
server.get('/login', async (
|
|
12
|
+
server.get('/login', async (_request, reply) => {
|
|
28
13
|
const redirectUrl = await authUtils.login(client, authStateNonce);
|
|
29
14
|
reply.redirect(redirectUrl);
|
|
30
15
|
});
|
|
31
16
|
server.get('/login-callback', async (request, reply) => {
|
|
32
|
-
const { tokenSet } = await authUtils.loginCallback(
|
|
33
|
-
client.callbackParams(request),
|
|
34
|
-
client,
|
|
35
|
-
authStateNonce,
|
|
36
|
-
);
|
|
17
|
+
const { tokenSet } = await authUtils.loginCallback(client.callbackParams(request.raw), client, authStateNonce);
|
|
37
18
|
const dirPath = tokenSetPath.substring(0, tokenSetPath.lastIndexOf(sep));
|
|
38
19
|
if (!existsSync(dirPath)) {
|
|
39
20
|
await mkdir(dirPath, { recursive: true });
|
|
40
21
|
}
|
|
41
|
-
await writeFile(tokenSetPath, JSON.stringify(tokenSet, null, 2), {
|
|
42
|
-
encoding: 'utf-8',
|
|
43
|
-
});
|
|
22
|
+
await writeFile(tokenSetPath, JSON.stringify(tokenSet, null, 2), { encoding: 'utf-8' });
|
|
44
23
|
if (tokenSet) {
|
|
45
24
|
reply.send('Login successful');
|
|
46
25
|
eventEmitter.emit('cli-auth:login');
|
|
@@ -1,25 +1,20 @@
|
|
|
1
|
-
import fastify from 'fastify';
|
|
2
1
|
import { env } from 'node:process';
|
|
2
|
+
import fastify from 'fastify';
|
|
3
3
|
import { Issuer } from 'openid-client';
|
|
4
4
|
import { auth } from './auth.js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @param {{tokenSetPath: string}} config
|
|
8
|
-
* @returns
|
|
9
|
-
*/
|
|
10
5
|
export const init = async (config) => {
|
|
11
6
|
if (!env.ISSUER_URL) {
|
|
12
7
|
console.error('Issuer URL not found');
|
|
13
|
-
return;
|
|
8
|
+
return null;
|
|
14
9
|
}
|
|
15
10
|
const issuer = await Issuer.discover(env.ISSUER_URL);
|
|
16
11
|
if (!issuer) {
|
|
17
12
|
console.error('Issuer not found');
|
|
18
|
-
return;
|
|
13
|
+
return null;
|
|
19
14
|
}
|
|
20
15
|
if (!env.IDS_CLIENT_ID || !env.IDS_CLIENT_SECRET) {
|
|
21
16
|
console.error('Client ID or Client Secret not found');
|
|
22
|
-
return;
|
|
17
|
+
return null;
|
|
23
18
|
}
|
|
24
19
|
const client = new issuer.Client({
|
|
25
20
|
client_id: env.IDS_CLIENT_ID,
|
|
@@ -29,16 +24,12 @@ export const init = async (config) => {
|
|
|
29
24
|
const auth_ = auth(client, config.tokenSetPath);
|
|
30
25
|
return {
|
|
31
26
|
start: async (eventEmitter) => {
|
|
32
|
-
const port = parseInt(env.PORT
|
|
27
|
+
const port = parseInt(env.PORT ?? '32231', 10);
|
|
33
28
|
auth_.mount(server, eventEmitter);
|
|
34
|
-
await server.listen({
|
|
35
|
-
port,
|
|
36
|
-
});
|
|
37
|
-
return server;
|
|
29
|
+
await server.listen({ port });
|
|
38
30
|
},
|
|
39
31
|
stop: async () => {
|
|
40
32
|
await server.close();
|
|
41
|
-
return server;
|
|
42
33
|
},
|
|
43
34
|
};
|
|
44
35
|
};
|
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
import { randomBytes } from 'node:crypto';
|
|
2
2
|
import { readFile, writeFile } from 'node:fs/promises';
|
|
3
3
|
import { env } from 'node:process';
|
|
4
|
-
|
|
5
4
|
export const authUtils = {
|
|
6
|
-
/**
|
|
7
|
-
* @param {import('openid-client').Client} client
|
|
8
|
-
* @param {{state: string, nonce: string}} authStateNonce
|
|
9
|
-
*/
|
|
10
5
|
login: async (client, authStateNonce) => {
|
|
6
|
+
const port = env.PORT ?? '32231';
|
|
11
7
|
const authorizationRequest = {
|
|
12
|
-
redirect_uri: `http://localhost:${
|
|
8
|
+
redirect_uri: `http://localhost:${port}/login-callback`,
|
|
13
9
|
scope: 'openid profile email address phone offline_access user',
|
|
14
10
|
state: randomBytes(16).toString('hex'),
|
|
15
11
|
nonce: randomBytes(16).toString('hex'),
|
|
16
|
-
response_type: client.response_types[0],
|
|
12
|
+
response_type: client.metadata.response_types?.[0] ?? 'code',
|
|
17
13
|
prompt: 'consent',
|
|
18
14
|
};
|
|
19
15
|
authStateNonce.state = authorizationRequest.state;
|
|
@@ -21,14 +17,7 @@ export const authUtils = {
|
|
|
21
17
|
const redirect = client.authorizationUrl(authorizationRequest);
|
|
22
18
|
return redirect;
|
|
23
19
|
},
|
|
24
|
-
/**
|
|
25
|
-
* @param {*} callbackParams
|
|
26
|
-
* @param {import('openid-client').Client} client
|
|
27
|
-
* @param {{state: string, nonce: string}} authStateNonce
|
|
28
|
-
* @returns {Promise<{redirect: string, tokenSet: null | any}>}
|
|
29
|
-
*/
|
|
30
20
|
loginCallback: async (callbackParams, client, authStateNonce) => {
|
|
31
|
-
/** @type {{redirect: string, tokenSet: null | any}} */
|
|
32
21
|
const result = {
|
|
33
22
|
redirect: '',
|
|
34
23
|
tokenSet: null,
|
|
@@ -37,7 +26,8 @@ export const authUtils = {
|
|
|
37
26
|
result.redirect = '/login';
|
|
38
27
|
return result;
|
|
39
28
|
}
|
|
40
|
-
const
|
|
29
|
+
const port = env.PORT ?? '32231';
|
|
30
|
+
const tokenset = await client.callback(`http://localhost:${port}/login-callback`, callbackParams, {
|
|
41
31
|
nonce: authStateNonce.nonce,
|
|
42
32
|
state: authStateNonce.state,
|
|
43
33
|
});
|
|
@@ -47,19 +37,10 @@ export const authUtils = {
|
|
|
47
37
|
result.redirect = '/login-success';
|
|
48
38
|
return result;
|
|
49
39
|
},
|
|
50
|
-
/**
|
|
51
|
-
* @param {import('openid-client').Client} client
|
|
52
|
-
* @param {string} tokenSetPath
|
|
53
|
-
* @returns {Promise<import('openid-client').IntrospectionResponse>}
|
|
54
|
-
*/
|
|
55
40
|
verifyToken: async (client, tokenSetPath) => {
|
|
56
41
|
const tokenSet = JSON.parse(await readFile(tokenSetPath, 'utf-8'));
|
|
57
42
|
return await client.introspect(tokenSet.access_token);
|
|
58
43
|
},
|
|
59
|
-
/**
|
|
60
|
-
* @param {import('openid-client').Client} client
|
|
61
|
-
* @param {string} tokenSetPath
|
|
62
|
-
*/
|
|
63
44
|
refreshToken: async (client, tokenSetPath) => {
|
|
64
45
|
const tokenSet = JSON.parse(await readFile(tokenSetPath, 'utf-8'));
|
|
65
46
|
const updatedTokenSet = await client.refresh(tokenSet.refresh_token);
|