pal-explorer-cli 0.4.12 → 0.4.13
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/README.md +149 -149
- package/bin/pal.js +63 -2
- package/extensions/@palexplorer/analytics/extension.json +20 -1
- package/extensions/@palexplorer/analytics/index.js +19 -9
- package/extensions/@palexplorer/audit/extension.json +14 -0
- package/extensions/@palexplorer/auth-email/extension.json +15 -0
- package/extensions/@palexplorer/auth-oauth/extension.json +15 -0
- package/extensions/@palexplorer/chat/extension.json +14 -0
- package/extensions/@palexplorer/discovery/extension.json +17 -0
- package/extensions/@palexplorer/discovery/index.js +1 -1
- package/extensions/@palexplorer/email-notifications/extension.json +23 -0
- package/extensions/@palexplorer/groups/extension.json +15 -0
- package/extensions/@palexplorer/share-links/extension.json +15 -0
- package/extensions/@palexplorer/sync/extension.json +16 -0
- package/extensions/@palexplorer/user-mgmt/extension.json +15 -0
- package/lib/capabilities.js +24 -24
- package/lib/commands/analytics.js +175 -175
- package/lib/commands/api-keys.js +131 -131
- package/lib/commands/audit.js +235 -235
- package/lib/commands/auth.js +137 -137
- package/lib/commands/backup.js +76 -76
- package/lib/commands/billing.js +148 -148
- package/lib/commands/chat.js +217 -217
- package/lib/commands/cloud-backup.js +231 -231
- package/lib/commands/comment.js +99 -99
- package/lib/commands/completion.js +203 -203
- package/lib/commands/compliance.js +218 -218
- package/lib/commands/config.js +136 -136
- package/lib/commands/connect.js +44 -44
- package/lib/commands/dept.js +294 -294
- package/lib/commands/device.js +146 -146
- package/lib/commands/download.js +240 -226
- package/lib/commands/explorer.js +178 -178
- package/lib/commands/extension.js +1060 -970
- package/lib/commands/favorite.js +90 -90
- package/lib/commands/federation.js +270 -270
- package/lib/commands/file.js +533 -533
- package/lib/commands/group.js +271 -271
- package/lib/commands/gui-share.js +29 -29
- package/lib/commands/init.js +61 -61
- package/lib/commands/invite.js +59 -59
- package/lib/commands/list.js +58 -58
- package/lib/commands/log.js +116 -116
- package/lib/commands/nearby.js +108 -108
- package/lib/commands/network.js +251 -251
- package/lib/commands/notify.js +198 -198
- package/lib/commands/org.js +273 -273
- package/lib/commands/pal.js +403 -180
- package/lib/commands/permissions.js +216 -216
- package/lib/commands/pin.js +97 -97
- package/lib/commands/protocol.js +357 -357
- package/lib/commands/rbac.js +147 -147
- package/lib/commands/recover.js +36 -36
- package/lib/commands/register.js +171 -171
- package/lib/commands/relay.js +131 -131
- package/lib/commands/remote.js +368 -368
- package/lib/commands/revoke.js +50 -50
- package/lib/commands/scanner.js +280 -280
- package/lib/commands/schedule.js +344 -344
- package/lib/commands/scim.js +203 -203
- package/lib/commands/search.js +181 -181
- package/lib/commands/serve.js +438 -438
- package/lib/commands/server.js +350 -350
- package/lib/commands/share-link.js +199 -199
- package/lib/commands/share.js +336 -323
- package/lib/commands/sso.js +200 -200
- package/lib/commands/status.js +145 -145
- package/lib/commands/stream.js +562 -562
- package/lib/commands/su.js +187 -187
- package/lib/commands/sync.js +979 -979
- package/lib/commands/transfers.js +152 -152
- package/lib/commands/uninstall.js +188 -188
- package/lib/commands/update.js +204 -204
- package/lib/commands/user.js +276 -276
- package/lib/commands/vfs.js +84 -84
- package/lib/commands/web-login.js +79 -79
- package/lib/commands/web.js +52 -52
- package/lib/commands/webhook.js +180 -180
- package/lib/commands/whoami.js +59 -59
- package/lib/commands/workspace.js +121 -121
- package/lib/core/billing.js +16 -5
- package/lib/core/dhtDiscovery.js +9 -2
- package/lib/core/discoveryClient.js +13 -7
- package/lib/core/extensions.js +142 -1
- package/lib/core/identity.js +33 -2
- package/lib/core/imageProcessor.js +109 -0
- package/lib/core/imageTorrent.js +167 -0
- package/lib/core/permissions.js +1 -1
- package/lib/core/pro.js +11 -4
- package/lib/core/serverList.js +4 -1
- package/lib/core/shares.js +12 -1
- package/lib/core/signalingServer.js +14 -2
- package/lib/core/su.js +1 -1
- package/lib/core/users.js +1 -1
- package/lib/protocol/messages.js +12 -3
- package/lib/utils/explorer.js +1 -1
- package/lib/utils/help.js +357 -357
- package/lib/utils/torrent.js +1 -0
- package/package.json +4 -3
|
@@ -1,218 +1,218 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
|
|
3
|
-
const SUPPORTED_MODULES = [
|
|
4
|
-
'gdpr', 'hipaa', 'soc2', 'pci', 'financial', 'fedramp',
|
|
5
|
-
'cmmc', 'iso27001', 'dora', 'itar', 'ccpa', 'ferpa',
|
|
6
|
-
];
|
|
7
|
-
|
|
8
|
-
export default function complianceCommand(program) {
|
|
9
|
-
const cmd = program
|
|
10
|
-
.command('compliance')
|
|
11
|
-
.description('manage compliance modules (GDPR, HIPAA, etc.)')
|
|
12
|
-
.addHelpText('after', `
|
|
13
|
-
Examples:
|
|
14
|
-
$
|
|
15
|
-
$
|
|
16
|
-
$
|
|
17
|
-
$
|
|
18
|
-
$
|
|
19
|
-
$
|
|
20
|
-
$
|
|
21
|
-
|
|
22
|
-
Supported modules: ${SUPPORTED_MODULES.join(', ')}
|
|
23
|
-
`)
|
|
24
|
-
.action(() => {
|
|
25
|
-
cmd.outputHelp();
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
cmd
|
|
29
|
-
.command('status')
|
|
30
|
-
.description('show which compliance modules are enabled')
|
|
31
|
-
.action(async () => {
|
|
32
|
-
try {
|
|
33
|
-
const extConfig = (await import('../utils/config.js')).default;
|
|
34
|
-
const cfg = extConfig.get('ext.compliance') || {};
|
|
35
|
-
const enabled = cfg.enabledModules || [];
|
|
36
|
-
|
|
37
|
-
console.log('');
|
|
38
|
-
console.log(chalk.cyan.bold('Compliance Modules'));
|
|
39
|
-
console.log('');
|
|
40
|
-
for (const mod of SUPPORTED_MODULES) {
|
|
41
|
-
const active = enabled.includes(mod);
|
|
42
|
-
const icon = active ? chalk.green('●') : chalk.gray('○');
|
|
43
|
-
console.log(` ${icon} ${active ? chalk.white(mod.toUpperCase()) : chalk.gray(mod.toUpperCase())}`);
|
|
44
|
-
}
|
|
45
|
-
console.log('');
|
|
46
|
-
} catch (err) {
|
|
47
|
-
console.log(chalk.red(`Failed to get status: ${err.message}`));
|
|
48
|
-
process.exitCode = 1;
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
cmd
|
|
53
|
-
.command('enable <module>')
|
|
54
|
-
.description('enable a compliance module')
|
|
55
|
-
.action(async (mod) => {
|
|
56
|
-
try {
|
|
57
|
-
const module = mod.toLowerCase();
|
|
58
|
-
if (!SUPPORTED_MODULES.includes(module)) {
|
|
59
|
-
console.log(chalk.red(`Unknown module "${mod}". Supported: ${SUPPORTED_MODULES.join(', ')}`));
|
|
60
|
-
process.exitCode = 1;
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const extConfig = (await import('../utils/config.js')).default;
|
|
65
|
-
const cfg = extConfig.get('ext.compliance') || {};
|
|
66
|
-
const enabled = cfg.enabledModules || [];
|
|
67
|
-
|
|
68
|
-
if (enabled.includes(module)) {
|
|
69
|
-
console.log(chalk.yellow(`${module.toUpperCase()} is already enabled.`));
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
enabled.push(module);
|
|
74
|
-
extConfig.set('ext.compliance', { ...cfg, enabledModules: enabled });
|
|
75
|
-
console.log(chalk.green(`✔ Enabled ${module.toUpperCase()} compliance module`));
|
|
76
|
-
} catch (err) {
|
|
77
|
-
console.log(chalk.red(`Failed to enable module: ${err.message}`));
|
|
78
|
-
process.exitCode = 1;
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
cmd
|
|
83
|
-
.command('disable <module>')
|
|
84
|
-
.description('disable a compliance module')
|
|
85
|
-
.action(async (mod) => {
|
|
86
|
-
try {
|
|
87
|
-
const module = mod.toLowerCase();
|
|
88
|
-
if (!SUPPORTED_MODULES.includes(module)) {
|
|
89
|
-
console.log(chalk.red(`Unknown module "${mod}". Supported: ${SUPPORTED_MODULES.join(', ')}`));
|
|
90
|
-
process.exitCode = 1;
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const extConfig = (await import('../utils/config.js')).default;
|
|
95
|
-
const cfg = extConfig.get('ext.compliance') || {};
|
|
96
|
-
const enabled = cfg.enabledModules || [];
|
|
97
|
-
|
|
98
|
-
if (!enabled.includes(module)) {
|
|
99
|
-
console.log(chalk.yellow(`${module.toUpperCase()} is not enabled.`));
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
extConfig.set('ext.compliance', {
|
|
104
|
-
...cfg,
|
|
105
|
-
enabledModules: enabled.filter(m => m !== module),
|
|
106
|
-
});
|
|
107
|
-
console.log(chalk.green(`✔ Disabled ${module.toUpperCase()} compliance module`));
|
|
108
|
-
} catch (err) {
|
|
109
|
-
console.log(chalk.red(`Failed to disable module: ${err.message}`));
|
|
110
|
-
process.exitCode = 1;
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
const consent = cmd
|
|
115
|
-
.command('consent')
|
|
116
|
-
.description('manage GDPR consent records')
|
|
117
|
-
.action(() => {
|
|
118
|
-
consent.outputHelp();
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
consent
|
|
122
|
-
.command('grant <publicKey>')
|
|
123
|
-
.description('record GDPR consent for a user')
|
|
124
|
-
.action(async (publicKey) => {
|
|
125
|
-
try {
|
|
126
|
-
const extConfig = (await import('../utils/config.js')).default;
|
|
127
|
-
const store = extConfig.get('ext_store.compliance-gdpr') || {};
|
|
128
|
-
|
|
129
|
-
store[`consent:${publicKey}`] = {
|
|
130
|
-
status: 'granted',
|
|
131
|
-
timestamp: new Date().toISOString(),
|
|
132
|
-
};
|
|
133
|
-
extConfig.set('ext_store.compliance-gdpr', store);
|
|
134
|
-
|
|
135
|
-
console.log(chalk.green(`✔ Consent granted for ${chalk.white(publicKey.slice(0, 16))}...`));
|
|
136
|
-
} catch (err) {
|
|
137
|
-
console.log(chalk.red(`Failed to grant consent: ${err.message}`));
|
|
138
|
-
process.exitCode = 1;
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
consent
|
|
143
|
-
.command('revoke <publicKey>')
|
|
144
|
-
.description('revoke GDPR consent for a user')
|
|
145
|
-
.action(async (publicKey) => {
|
|
146
|
-
try {
|
|
147
|
-
const extConfig = (await import('../utils/config.js')).default;
|
|
148
|
-
const store = extConfig.get('ext_store.compliance-gdpr') || {};
|
|
149
|
-
|
|
150
|
-
store[`consent:${publicKey}`] = {
|
|
151
|
-
status: 'revoked',
|
|
152
|
-
timestamp: new Date().toISOString(),
|
|
153
|
-
};
|
|
154
|
-
extConfig.set('ext_store.compliance-gdpr', store);
|
|
155
|
-
|
|
156
|
-
console.log(chalk.green(`✔ Consent revoked for ${chalk.white(publicKey.slice(0, 16))}...`));
|
|
157
|
-
} catch (err) {
|
|
158
|
-
console.log(chalk.red(`Failed to revoke consent: ${err.message}`));
|
|
159
|
-
process.exitCode = 1;
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
cmd
|
|
164
|
-
.command('erasure <publicKey>')
|
|
165
|
-
.description('GDPR right to erasure — mark user data for deletion')
|
|
166
|
-
.action(async (publicKey) => {
|
|
167
|
-
try {
|
|
168
|
-
const extConfig = (await import('../utils/config.js')).default;
|
|
169
|
-
const store = extConfig.get('ext_store.compliance-gdpr') || {};
|
|
170
|
-
|
|
171
|
-
store[`erasure:${publicKey}`] = {
|
|
172
|
-
status: 'pending',
|
|
173
|
-
requestedAt: new Date().toISOString(),
|
|
174
|
-
};
|
|
175
|
-
store[`consent:${publicKey}`] = {
|
|
176
|
-
status: 'revoked',
|
|
177
|
-
timestamp: new Date().toISOString(),
|
|
178
|
-
};
|
|
179
|
-
extConfig.set('ext_store.compliance-gdpr', store);
|
|
180
|
-
|
|
181
|
-
console.log(chalk.green(`✔ Erasure request recorded for ${chalk.white(publicKey.slice(0, 16))}...`));
|
|
182
|
-
console.log(chalk.gray(' User data marked for deletion. Consent auto-revoked.'));
|
|
183
|
-
} catch (err) {
|
|
184
|
-
console.log(chalk.red(`Failed to record erasure: ${err.message}`));
|
|
185
|
-
process.exitCode = 1;
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
cmd
|
|
190
|
-
.command('export <publicKey>')
|
|
191
|
-
.description('GDPR data subject access request — export user data')
|
|
192
|
-
.action(async (publicKey) => {
|
|
193
|
-
try {
|
|
194
|
-
const extConfig = (await import('../utils/config.js')).default;
|
|
195
|
-
const store = extConfig.get('ext_store.compliance-gdpr') || {};
|
|
196
|
-
|
|
197
|
-
const consentRecord = store[`consent:${publicKey}`];
|
|
198
|
-
const erasureRecord = store[`erasure:${publicKey}`];
|
|
199
|
-
|
|
200
|
-
const exportData = {
|
|
201
|
-
publicKey,
|
|
202
|
-
exportedAt: new Date().toISOString(),
|
|
203
|
-
consent: consentRecord || null,
|
|
204
|
-
erasure: erasureRecord || null,
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
const filename = `gdpr-export-${publicKey.slice(0, 8)}-${Date.now()}.json`;
|
|
208
|
-
const fs = await import('fs');
|
|
209
|
-
fs.writeFileSync(filename, JSON.stringify(exportData, null, 2));
|
|
210
|
-
|
|
211
|
-
console.log(chalk.green(`✔ Data exported for ${chalk.white(publicKey.slice(0, 16))}...`));
|
|
212
|
-
console.log(` File: ${chalk.white(filename)}`);
|
|
213
|
-
} catch (err) {
|
|
214
|
-
console.log(chalk.red(`Failed to export data: ${err.message}`));
|
|
215
|
-
process.exitCode = 1;
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
|
-
}
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
|
|
3
|
+
const SUPPORTED_MODULES = [
|
|
4
|
+
'gdpr', 'hipaa', 'soc2', 'pci', 'financial', 'fedramp',
|
|
5
|
+
'cmmc', 'iso27001', 'dora', 'itar', 'ccpa', 'ferpa',
|
|
6
|
+
];
|
|
7
|
+
|
|
8
|
+
export default function complianceCommand(program) {
|
|
9
|
+
const cmd = program
|
|
10
|
+
.command('compliance')
|
|
11
|
+
.description('manage compliance modules (GDPR, HIPAA, etc.)')
|
|
12
|
+
.addHelpText('after', `
|
|
13
|
+
Examples:
|
|
14
|
+
$ pal compliance status Show enabled compliance modules
|
|
15
|
+
$ pal compliance enable gdpr Enable GDPR compliance
|
|
16
|
+
$ pal compliance disable hipaa Disable HIPAA compliance
|
|
17
|
+
$ pal compliance consent grant <pubkey> Record GDPR consent
|
|
18
|
+
$ pal compliance consent revoke <pubkey> Revoke GDPR consent
|
|
19
|
+
$ pal compliance erasure <pubkey> GDPR right to erasure
|
|
20
|
+
$ pal compliance export <pubkey> GDPR data subject access request
|
|
21
|
+
|
|
22
|
+
Supported modules: ${SUPPORTED_MODULES.join(', ')}
|
|
23
|
+
`)
|
|
24
|
+
.action(() => {
|
|
25
|
+
cmd.outputHelp();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
cmd
|
|
29
|
+
.command('status')
|
|
30
|
+
.description('show which compliance modules are enabled')
|
|
31
|
+
.action(async () => {
|
|
32
|
+
try {
|
|
33
|
+
const extConfig = (await import('../utils/config.js')).default;
|
|
34
|
+
const cfg = extConfig.get('ext.compliance') || {};
|
|
35
|
+
const enabled = cfg.enabledModules || [];
|
|
36
|
+
|
|
37
|
+
console.log('');
|
|
38
|
+
console.log(chalk.cyan.bold('Compliance Modules'));
|
|
39
|
+
console.log('');
|
|
40
|
+
for (const mod of SUPPORTED_MODULES) {
|
|
41
|
+
const active = enabled.includes(mod);
|
|
42
|
+
const icon = active ? chalk.green('●') : chalk.gray('○');
|
|
43
|
+
console.log(` ${icon} ${active ? chalk.white(mod.toUpperCase()) : chalk.gray(mod.toUpperCase())}`);
|
|
44
|
+
}
|
|
45
|
+
console.log('');
|
|
46
|
+
} catch (err) {
|
|
47
|
+
console.log(chalk.red(`Failed to get status: ${err.message}`));
|
|
48
|
+
process.exitCode = 1;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
cmd
|
|
53
|
+
.command('enable <module>')
|
|
54
|
+
.description('enable a compliance module')
|
|
55
|
+
.action(async (mod) => {
|
|
56
|
+
try {
|
|
57
|
+
const module = mod.toLowerCase();
|
|
58
|
+
if (!SUPPORTED_MODULES.includes(module)) {
|
|
59
|
+
console.log(chalk.red(`Unknown module "${mod}". Supported: ${SUPPORTED_MODULES.join(', ')}`));
|
|
60
|
+
process.exitCode = 1;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const extConfig = (await import('../utils/config.js')).default;
|
|
65
|
+
const cfg = extConfig.get('ext.compliance') || {};
|
|
66
|
+
const enabled = cfg.enabledModules || [];
|
|
67
|
+
|
|
68
|
+
if (enabled.includes(module)) {
|
|
69
|
+
console.log(chalk.yellow(`${module.toUpperCase()} is already enabled.`));
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
enabled.push(module);
|
|
74
|
+
extConfig.set('ext.compliance', { ...cfg, enabledModules: enabled });
|
|
75
|
+
console.log(chalk.green(`✔ Enabled ${module.toUpperCase()} compliance module`));
|
|
76
|
+
} catch (err) {
|
|
77
|
+
console.log(chalk.red(`Failed to enable module: ${err.message}`));
|
|
78
|
+
process.exitCode = 1;
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
cmd
|
|
83
|
+
.command('disable <module>')
|
|
84
|
+
.description('disable a compliance module')
|
|
85
|
+
.action(async (mod) => {
|
|
86
|
+
try {
|
|
87
|
+
const module = mod.toLowerCase();
|
|
88
|
+
if (!SUPPORTED_MODULES.includes(module)) {
|
|
89
|
+
console.log(chalk.red(`Unknown module "${mod}". Supported: ${SUPPORTED_MODULES.join(', ')}`));
|
|
90
|
+
process.exitCode = 1;
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const extConfig = (await import('../utils/config.js')).default;
|
|
95
|
+
const cfg = extConfig.get('ext.compliance') || {};
|
|
96
|
+
const enabled = cfg.enabledModules || [];
|
|
97
|
+
|
|
98
|
+
if (!enabled.includes(module)) {
|
|
99
|
+
console.log(chalk.yellow(`${module.toUpperCase()} is not enabled.`));
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
extConfig.set('ext.compliance', {
|
|
104
|
+
...cfg,
|
|
105
|
+
enabledModules: enabled.filter(m => m !== module),
|
|
106
|
+
});
|
|
107
|
+
console.log(chalk.green(`✔ Disabled ${module.toUpperCase()} compliance module`));
|
|
108
|
+
} catch (err) {
|
|
109
|
+
console.log(chalk.red(`Failed to disable module: ${err.message}`));
|
|
110
|
+
process.exitCode = 1;
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const consent = cmd
|
|
115
|
+
.command('consent')
|
|
116
|
+
.description('manage GDPR consent records')
|
|
117
|
+
.action(() => {
|
|
118
|
+
consent.outputHelp();
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
consent
|
|
122
|
+
.command('grant <publicKey>')
|
|
123
|
+
.description('record GDPR consent for a user')
|
|
124
|
+
.action(async (publicKey) => {
|
|
125
|
+
try {
|
|
126
|
+
const extConfig = (await import('../utils/config.js')).default;
|
|
127
|
+
const store = extConfig.get('ext_store.compliance-gdpr') || {};
|
|
128
|
+
|
|
129
|
+
store[`consent:${publicKey}`] = {
|
|
130
|
+
status: 'granted',
|
|
131
|
+
timestamp: new Date().toISOString(),
|
|
132
|
+
};
|
|
133
|
+
extConfig.set('ext_store.compliance-gdpr', store);
|
|
134
|
+
|
|
135
|
+
console.log(chalk.green(`✔ Consent granted for ${chalk.white(publicKey.slice(0, 16))}...`));
|
|
136
|
+
} catch (err) {
|
|
137
|
+
console.log(chalk.red(`Failed to grant consent: ${err.message}`));
|
|
138
|
+
process.exitCode = 1;
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
consent
|
|
143
|
+
.command('revoke <publicKey>')
|
|
144
|
+
.description('revoke GDPR consent for a user')
|
|
145
|
+
.action(async (publicKey) => {
|
|
146
|
+
try {
|
|
147
|
+
const extConfig = (await import('../utils/config.js')).default;
|
|
148
|
+
const store = extConfig.get('ext_store.compliance-gdpr') || {};
|
|
149
|
+
|
|
150
|
+
store[`consent:${publicKey}`] = {
|
|
151
|
+
status: 'revoked',
|
|
152
|
+
timestamp: new Date().toISOString(),
|
|
153
|
+
};
|
|
154
|
+
extConfig.set('ext_store.compliance-gdpr', store);
|
|
155
|
+
|
|
156
|
+
console.log(chalk.green(`✔ Consent revoked for ${chalk.white(publicKey.slice(0, 16))}...`));
|
|
157
|
+
} catch (err) {
|
|
158
|
+
console.log(chalk.red(`Failed to revoke consent: ${err.message}`));
|
|
159
|
+
process.exitCode = 1;
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
cmd
|
|
164
|
+
.command('erasure <publicKey>')
|
|
165
|
+
.description('GDPR right to erasure — mark user data for deletion')
|
|
166
|
+
.action(async (publicKey) => {
|
|
167
|
+
try {
|
|
168
|
+
const extConfig = (await import('../utils/config.js')).default;
|
|
169
|
+
const store = extConfig.get('ext_store.compliance-gdpr') || {};
|
|
170
|
+
|
|
171
|
+
store[`erasure:${publicKey}`] = {
|
|
172
|
+
status: 'pending',
|
|
173
|
+
requestedAt: new Date().toISOString(),
|
|
174
|
+
};
|
|
175
|
+
store[`consent:${publicKey}`] = {
|
|
176
|
+
status: 'revoked',
|
|
177
|
+
timestamp: new Date().toISOString(),
|
|
178
|
+
};
|
|
179
|
+
extConfig.set('ext_store.compliance-gdpr', store);
|
|
180
|
+
|
|
181
|
+
console.log(chalk.green(`✔ Erasure request recorded for ${chalk.white(publicKey.slice(0, 16))}...`));
|
|
182
|
+
console.log(chalk.gray(' User data marked for deletion. Consent auto-revoked.'));
|
|
183
|
+
} catch (err) {
|
|
184
|
+
console.log(chalk.red(`Failed to record erasure: ${err.message}`));
|
|
185
|
+
process.exitCode = 1;
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
cmd
|
|
190
|
+
.command('export <publicKey>')
|
|
191
|
+
.description('GDPR data subject access request — export user data')
|
|
192
|
+
.action(async (publicKey) => {
|
|
193
|
+
try {
|
|
194
|
+
const extConfig = (await import('../utils/config.js')).default;
|
|
195
|
+
const store = extConfig.get('ext_store.compliance-gdpr') || {};
|
|
196
|
+
|
|
197
|
+
const consentRecord = store[`consent:${publicKey}`];
|
|
198
|
+
const erasureRecord = store[`erasure:${publicKey}`];
|
|
199
|
+
|
|
200
|
+
const exportData = {
|
|
201
|
+
publicKey,
|
|
202
|
+
exportedAt: new Date().toISOString(),
|
|
203
|
+
consent: consentRecord || null,
|
|
204
|
+
erasure: erasureRecord || null,
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
const filename = `gdpr-export-${publicKey.slice(0, 8)}-${Date.now()}.json`;
|
|
208
|
+
const fs = await import('fs');
|
|
209
|
+
fs.writeFileSync(filename, JSON.stringify(exportData, null, 2));
|
|
210
|
+
|
|
211
|
+
console.log(chalk.green(`✔ Data exported for ${chalk.white(publicKey.slice(0, 16))}...`));
|
|
212
|
+
console.log(` File: ${chalk.white(filename)}`);
|
|
213
|
+
} catch (err) {
|
|
214
|
+
console.log(chalk.red(`Failed to export data: ${err.message}`));
|
|
215
|
+
process.exitCode = 1;
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
}
|