@undefineds.co/xpod 0.1.7 → 0.2.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/README.md +164 -3
- package/config/cli.json +9 -71
- package/config/cloud.json +34 -7
- package/config/local.json +6 -2
- package/config/resolver.json +11 -49
- package/config/runtime-open.json +22 -0
- package/config/xpod.base.json +32 -0
- package/config/xpod.cluster.json +2 -44
- package/config/xpod.json +5 -2
- package/dist/agents/AgentExecutorFactory.js +1 -1
- package/dist/agents/AgentExecutorFactory.js.map +1 -1
- package/dist/agents/AgentManager.js +1 -1
- package/dist/agents/AgentManager.js.map +1 -1
- package/dist/agents/config/agent-meta-schema.d.ts +7 -7
- package/dist/agents/config/agent-meta-schema.js +1 -1
- package/dist/agents/config/agent-meta-schema.js.map +1 -1
- package/dist/agents/config/resolve.js +1 -1
- package/dist/agents/config/resolve.js.map +1 -1
- package/dist/agents/schema/agent-config.d.ts +18 -18
- package/dist/agents/schema/agent-config.js +1 -1
- package/dist/agents/schema/agent-config.js.map +1 -1
- package/dist/agents/schema/tables.d.ts +8 -8
- package/dist/agents/schema/tables.js +1 -1
- package/dist/agents/schema/tables.js.map +1 -1
- package/dist/ai/schema/config.d.ts +7 -7
- package/dist/ai/schema/config.js +1 -1
- package/dist/ai/schema/config.js.map +1 -1
- package/dist/ai/schema/model.d.ts +13 -13
- package/dist/ai/schema/model.js +1 -1
- package/dist/ai/schema/model.js.map +1 -1
- package/dist/ai/schema/provider.d.ts +7 -7
- package/dist/ai/schema/provider.js +1 -1
- package/dist/ai/schema/provider.js.map +1 -1
- package/dist/ai/schema/vector-store.d.ts +17 -17
- package/dist/ai/schema/vector-store.js +1 -1
- package/dist/ai/schema/vector-store.js.map +1 -1
- package/dist/ai/service/CredentialReaderImpl.js +1 -1
- package/dist/ai/service/CredentialReaderImpl.js.map +1 -1
- package/dist/ai/service/DefaultAiConfigService.js.map +1 -1
- package/dist/api/ApiServer.d.ts +3 -1
- package/dist/api/ApiServer.js +14 -1
- package/dist/api/ApiServer.js.map +1 -1
- package/dist/api/auth/AuthContext.d.ts +12 -1
- package/dist/api/auth/AuthContext.js +18 -1
- package/dist/api/auth/AuthContext.js.map +1 -1
- package/dist/api/auth/ClientCredentialsAuthenticator.d.ts +0 -1
- package/dist/api/auth/ClientCredentialsAuthenticator.js.map +1 -1
- package/dist/api/auth/ServiceTokenAuthenticator.d.ts +18 -0
- package/dist/api/auth/ServiceTokenAuthenticator.js +50 -0
- package/dist/api/auth/ServiceTokenAuthenticator.js.map +1 -0
- package/dist/api/auth/index.d.ts +1 -0
- package/dist/api/auth/index.js +1 -0
- package/dist/api/auth/index.js.map +1 -1
- package/dist/api/chatkit/ai-provider.d.ts +0 -10
- package/dist/api/chatkit/ai-provider.js +11 -120
- package/dist/api/chatkit/ai-provider.js.map +1 -1
- package/dist/api/chatkit/default-agent.js +11 -8
- package/dist/api/chatkit/default-agent.js.map +1 -1
- package/dist/api/chatkit/pod-store.d.ts +6 -0
- package/dist/api/chatkit/pod-store.js +103 -36
- package/dist/api/chatkit/pod-store.js.map +1 -1
- package/dist/api/chatkit/schema.d.ts +32 -26
- package/dist/api/chatkit/schema.js +16 -8
- package/dist/api/chatkit/schema.js.map +1 -1
- package/dist/api/container/business-token.d.ts +9 -0
- package/dist/api/container/business-token.js +32 -0
- package/dist/api/container/business-token.js.map +1 -0
- package/dist/api/container/cloud.js +36 -12
- package/dist/api/container/cloud.js.map +1 -1
- package/dist/api/container/common.js +13 -5
- package/dist/api/container/common.js.map +1 -1
- package/dist/api/container/index.js +94 -14
- package/dist/api/container/index.js.map +1 -1
- package/dist/api/container/local.js +2 -1
- package/dist/api/container/local.js.map +1 -1
- package/dist/api/container/routes.js +81 -9
- package/dist/api/container/routes.js.map +1 -1
- package/dist/api/container/types.d.ts +8 -6
- package/dist/api/container/types.js.map +1 -1
- package/dist/api/handlers/AdminHandler.js +9 -9
- package/dist/api/handlers/AdminHandler.js.map +1 -1
- package/dist/api/handlers/ApiKeyHandler.js +0 -6
- package/dist/api/handlers/ApiKeyHandler.js.map +1 -1
- package/dist/api/handlers/EdgeNodeSignalHandler.d.ts +17 -0
- package/dist/api/handlers/EdgeNodeSignalHandler.js +171 -0
- package/dist/api/handlers/EdgeNodeSignalHandler.js.map +1 -0
- package/dist/api/handlers/PodManagementHandler.d.ts +5 -4
- package/dist/api/handlers/PodManagementHandler.js +11 -10
- package/dist/api/handlers/PodManagementHandler.js.map +1 -1
- package/dist/api/handlers/ProvisionHandler.d.ts +42 -0
- package/dist/api/handlers/ProvisionHandler.js +161 -0
- package/dist/api/handlers/ProvisionHandler.js.map +1 -0
- package/dist/api/handlers/QuotaHandler.d.ts +7 -7
- package/dist/api/handlers/QuotaHandler.js +143 -73
- package/dist/api/handlers/QuotaHandler.js.map +1 -1
- package/dist/api/handlers/SubdomainClientHandler.js +2 -2
- package/dist/api/handlers/SubdomainClientHandler.js.map +1 -1
- package/dist/api/handlers/SubdomainHandler.js +13 -8
- package/dist/api/handlers/SubdomainHandler.js.map +1 -1
- package/dist/api/handlers/UsageHandler.d.ts +14 -0
- package/dist/api/handlers/UsageHandler.js +123 -0
- package/dist/api/handlers/UsageHandler.js.map +1 -0
- package/dist/api/handlers/index.d.ts +3 -1
- package/dist/api/handlers/index.js +3 -1
- package/dist/api/handlers/index.js.map +1 -1
- package/dist/api/main.js +18 -0
- package/dist/api/main.js.map +1 -1
- package/dist/api/middleware/OpenAuthMiddleware.d.ts +12 -0
- package/dist/api/middleware/OpenAuthMiddleware.js +27 -0
- package/dist/api/middleware/OpenAuthMiddleware.js.map +1 -0
- package/dist/api/runtime.d.ts +15 -0
- package/dist/api/runtime.js +125 -0
- package/dist/api/runtime.js.map +1 -0
- package/dist/api/service/VectorStoreService.js +1 -1
- package/dist/api/service/VectorStoreService.js.map +1 -1
- package/dist/api/service/VercelChatService.d.ts +16 -7
- package/dist/api/service/VercelChatService.js +98 -178
- package/dist/api/service/VercelChatService.js.map +1 -1
- package/dist/api/store/DrizzleClientCredentialsStore.d.ts +6 -11
- package/dist/api/store/DrizzleClientCredentialsStore.js +9 -39
- package/dist/api/store/DrizzleClientCredentialsStore.js.map +1 -1
- package/dist/authorization/AuthModeSelector.d.ts +10 -0
- package/dist/authorization/AuthModeSelector.js +27 -0
- package/dist/authorization/AuthModeSelector.js.map +1 -0
- package/dist/authorization/AuthModeSelector.jsonld +81 -0
- package/dist/cli/commands/account.d.ts +6 -0
- package/dist/cli/commands/account.js +119 -0
- package/dist/cli/commands/account.js.map +1 -0
- package/dist/cli/commands/auth.js +20 -29
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/commands/backup.d.ts +15 -0
- package/dist/cli/commands/backup.js +286 -0
- package/dist/cli/commands/backup.js.map +1 -0
- package/dist/cli/commands/config.d.ts +34 -3
- package/dist/cli/commands/config.js +195 -258
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts +6 -0
- package/dist/cli/commands/doctor.js +94 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/pod.d.ts +6 -0
- package/dist/cli/commands/pod.js +124 -0
- package/dist/cli/commands/pod.js.map +1 -0
- package/dist/cli/commands/start.js +28 -5
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/index.js +9 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/lib/credentials-store.d.ts +17 -0
- package/dist/cli/lib/credentials-store.js +73 -0
- package/dist/cli/lib/credentials-store.js.map +1 -0
- package/dist/cli/lib/css-account.d.ts +17 -0
- package/dist/cli/lib/css-account.js +56 -0
- package/dist/cli/lib/css-account.js.map +1 -1
- package/dist/cli/lib/pod-thread-store.d.ts +57 -0
- package/dist/cli/lib/pod-thread-store.js +310 -0
- package/dist/cli/lib/pod-thread-store.js.map +1 -0
- package/dist/cli/lib/solid-auth.d.ts +20 -0
- package/dist/cli/lib/solid-auth.js +70 -0
- package/dist/cli/lib/solid-auth.js.map +1 -0
- package/dist/components/components.jsonld +5 -8
- package/dist/components/context.jsonld +114 -244
- package/dist/credential/schema/tables.d.ts +14 -14
- package/dist/credential/schema/tables.js +1 -1
- package/dist/credential/schema/tables.js.map +1 -1
- package/dist/edge/EdgeNodeAgent.js +2 -2
- package/dist/edge/EdgeNodeAgent.js.map +1 -1
- package/dist/edge/EdgeNodeDnsCoordinator.d.ts +1 -7
- package/dist/edge/EdgeNodeDnsCoordinator.js +31 -41
- package/dist/edge/EdgeNodeDnsCoordinator.js.map +1 -1
- package/dist/edge/EdgeNodeDnsCoordinator.jsonld +1 -27
- package/dist/edge/EdgeNodeModeDetector.d.ts +1 -1
- package/dist/edge/EdgeNodeModeDetector.js +9 -11
- package/dist/edge/EdgeNodeModeDetector.js.map +1 -1
- package/dist/http/ClusterIngressRouter.js +3 -3
- package/dist/http/ClusterIngressRouter.js.map +1 -1
- package/dist/http/ClusterWebSocketConfigurator.js +2 -2
- package/dist/http/ClusterWebSocketConfigurator.js.map +1 -1
- package/dist/http/PodRoutingHttpHandler.js +2 -2
- package/dist/http/PodRoutingHttpHandler.js.map +1 -1
- package/dist/http/cluster/PodMigrationHttpHandler.d.ts +1 -1
- package/dist/http/cluster/PodMigrationHttpHandler.js +1 -1
- package/dist/http/cluster/PodMigrationHttpHandler.js.map +1 -1
- package/dist/identity/drizzle/EdgeNodeRepository.d.ts +37 -4
- package/dist/identity/drizzle/EdgeNodeRepository.js +120 -128
- package/dist/identity/drizzle/EdgeNodeRepository.js.map +1 -1
- package/dist/identity/drizzle/ServiceTokenRepository.d.ts +52 -0
- package/dist/identity/drizzle/ServiceTokenRepository.js +142 -0
- package/dist/identity/drizzle/ServiceTokenRepository.js.map +1 -0
- package/dist/identity/drizzle/db.d.ts +9 -0
- package/dist/identity/drizzle/db.js +235 -3
- package/dist/identity/drizzle/db.js.map +1 -1
- package/dist/identity/drizzle/schema.pg.d.ts +5 -0
- package/dist/identity/drizzle/schema.pg.js +49 -20
- package/dist/identity/drizzle/schema.pg.js.map +1 -1
- package/dist/identity/drizzle/schema.sqlite.d.ts +332 -57
- package/dist/identity/drizzle/schema.sqlite.js +48 -18
- package/dist/identity/drizzle/schema.sqlite.js.map +1 -1
- package/dist/identity/oidc/AutoDetectIdentityProviderHandler.js +6 -4
- package/dist/identity/oidc/AutoDetectIdentityProviderHandler.js.map +1 -1
- package/dist/index.d.ts +6 -9
- package/dist/index.js +12 -14
- package/dist/index.js.map +1 -1
- package/dist/main.js +25 -8
- package/dist/main.js.map +1 -1
- package/dist/provision/ProvisionCodeCodec.d.ts +39 -0
- package/dist/provision/ProvisionCodeCodec.js +65 -0
- package/dist/provision/ProvisionCodeCodec.js.map +1 -0
- package/dist/provision/ProvisionCodeCodec.jsonld +47 -0
- package/dist/provision/ProvisionPodCreator.d.ts +20 -0
- package/dist/provision/ProvisionPodCreator.js +84 -0
- package/dist/provision/ProvisionPodCreator.js.map +1 -0
- package/dist/provision/ProvisionPodCreator.jsonld +118 -0
- package/dist/quota/DrizzleQuotaService.d.ts +17 -3
- package/dist/quota/DrizzleQuotaService.js +108 -8
- package/dist/quota/DrizzleQuotaService.js.map +1 -1
- package/dist/quota/DrizzleQuotaService.jsonld +33 -22
- package/dist/quota/NoopQuotaService.d.ts +7 -1
- package/dist/quota/NoopQuotaService.js +12 -0
- package/dist/quota/NoopQuotaService.js.map +1 -1
- package/dist/quota/NoopQuotaService.jsonld +24 -0
- package/dist/quota/QuotaService.d.ts +17 -0
- package/dist/quota/QuotaService.js +5 -0
- package/dist/quota/QuotaService.js.map +1 -1
- package/dist/quota/QuotaService.jsonld +50 -0
- package/dist/runtime/Proxy.d.ts +22 -4
- package/dist/runtime/Proxy.js +154 -35
- package/dist/runtime/Proxy.js.map +1 -1
- package/dist/runtime/XpodRuntime.d.ts +49 -0
- package/dist/runtime/XpodRuntime.js +374 -0
- package/dist/runtime/XpodRuntime.js.map +1 -0
- package/dist/runtime/env-utils.d.ts +2 -0
- package/dist/runtime/env-utils.js +55 -0
- package/dist/runtime/env-utils.js.map +1 -0
- package/dist/runtime/index.d.ts +4 -0
- package/dist/runtime/index.js +8 -1
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/socket-fetch.d.ts +1 -0
- package/dist/runtime/socket-fetch.js +72 -0
- package/dist/runtime/socket-fetch.js.map +1 -0
- package/dist/runtime/socket-http.d.ts +1 -0
- package/dist/runtime/socket-http.js +142 -0
- package/dist/runtime/socket-http.js.map +1 -0
- package/dist/runtime/socket-utils.d.ts +2 -0
- package/dist/runtime/socket-utils.js +34 -0
- package/dist/runtime/socket-utils.js.map +1 -0
- package/dist/service/{EdgeNodeHeartbeatService.d.ts → EdgeNodeSignalClient.d.ts} +3 -3
- package/dist/service/{EdgeNodeHeartbeatService.js → EdgeNodeSignalClient.js} +4 -4
- package/dist/service/EdgeNodeSignalClient.js.map +1 -0
- package/dist/service/PodMigrationService.d.ts +1 -2
- package/dist/service/PodMigrationService.js +1 -2
- package/dist/service/PodMigrationService.js.map +1 -1
- package/dist/storage/SparqlUpdateResourceStore.js +1 -1
- package/dist/storage/SparqlUpdateResourceStore.js.map +1 -1
- package/dist/storage/accessors/MinioDataAccessor.d.ts +6 -0
- package/dist/storage/accessors/MinioDataAccessor.js +10 -0
- package/dist/storage/accessors/MinioDataAccessor.js.map +1 -1
- package/dist/storage/accessors/MinioDataAccessor.jsonld +4 -0
- package/dist/storage/accessors/MixDataAccessor.d.ts +2 -1
- package/dist/storage/accessors/MixDataAccessor.js +12 -1
- package/dist/storage/accessors/MixDataAccessor.js.map +1 -1
- package/dist/storage/accessors/MixDataAccessor.jsonld +19 -0
- package/dist/storage/locking/UrlAwareRedisLocker.d.ts +18 -0
- package/dist/storage/locking/UrlAwareRedisLocker.js +60 -0
- package/dist/storage/locking/UrlAwareRedisLocker.js.map +1 -0
- package/dist/storage/locking/UrlAwareRedisLocker.jsonld +123 -0
- package/dist/storage/quota/UsageRepository.d.ts +41 -8
- package/dist/storage/quota/UsageRepository.js +252 -50
- package/dist/storage/quota/UsageRepository.js.map +1 -1
- package/dist/storage/sparql/ComunicaQuintEngine.d.ts +9 -0
- package/dist/storage/sparql/ComunicaQuintEngine.js +50 -9
- package/dist/storage/sparql/ComunicaQuintEngine.js.map +1 -1
- package/dist/storage/sparql/QueryOptimizer.js +13 -1
- package/dist/storage/sparql/QueryOptimizer.js.map +1 -1
- package/dist/storage/sparql/QuintQuerySource.d.ts +14 -0
- package/dist/storage/sparql/QuintQuerySource.js +152 -1
- package/dist/storage/sparql/QuintQuerySource.js.map +1 -1
- package/dist/storage/sparql/SubgraphQueryEngine.d.ts +1 -0
- package/dist/storage/sparql/SubgraphQueryEngine.js +6 -2
- package/dist/storage/sparql/SubgraphQueryEngine.js.map +1 -1
- package/dist/storage/sparql/SubgraphQueryEngine.jsonld +4 -0
- package/dist/subdomain/SubdomainClient.d.ts +3 -3
- package/dist/subdomain/SubdomainClient.js +1 -1
- package/dist/subdomain/SubdomainClient.js.map +1 -1
- package/dist/subdomain/SubdomainService.d.ts +15 -16
- package/dist/subdomain/SubdomainService.js +80 -54
- package/dist/subdomain/SubdomainService.js.map +1 -1
- package/dist/subdomain/SubdomainService.jsonld +22 -26
- package/dist/supervisor/Supervisor.d.ts +7 -2
- package/dist/supervisor/Supervisor.js +33 -1
- package/dist/supervisor/Supervisor.js.map +1 -1
- package/dist/task/DrizzleTaskQueue.d.ts +1 -1
- package/dist/task/DrizzleTaskQueue.js +1 -1
- package/dist/task/DrizzleTaskQueue.js.map +1 -1
- package/dist/task/schema.d.ts +10 -10
- package/dist/task/schema.js +1 -1
- package/dist/task/schema.js.map +1 -1
- package/dist/test-utils/index.d.ts +4 -0
- package/dist/test-utils/index.js +8 -0
- package/dist/test-utils/index.js.map +1 -0
- package/dist/test-utils/no-auth-xpod.d.ts +11 -0
- package/dist/test-utils/no-auth-xpod.js +25 -0
- package/dist/test-utils/no-auth-xpod.js.map +1 -0
- package/dist/test-utils/seed-pod.d.ts +5 -0
- package/dist/test-utils/seed-pod.js +61 -0
- package/dist/test-utils/seed-pod.js.map +1 -0
- package/package.json +38 -10
- package/templates/identity/account/create-pod.html.ejs +110 -0
- package/templates/main.html.ejs +10 -0
- package/dist/api/handlers/DevHandler.d.ts +0 -18
- package/dist/api/handlers/DevHandler.js +0 -276
- package/dist/api/handlers/DevHandler.js.map +0 -1
- package/dist/api/handlers/SignalHandler.d.ts +0 -13
- package/dist/api/handlers/SignalHandler.js +0 -122
- package/dist/api/handlers/SignalHandler.js.map +0 -1
- package/dist/gateway/Proxy.d.ts +0 -24
- package/dist/gateway/Proxy.js +0 -209
- package/dist/gateway/Proxy.js.map +0 -1
- package/dist/gateway/Supervisor.d.ts +0 -2
- package/dist/gateway/Supervisor.js +0 -7
- package/dist/gateway/Supervisor.js.map +0 -1
- package/dist/gateway/port-finder.d.ts +0 -4
- package/dist/gateway/port-finder.js +0 -15
- package/dist/gateway/port-finder.js.map +0 -1
- package/dist/gateway/types.d.ts +0 -1
- package/dist/gateway/types.js +0 -3
- package/dist/gateway/types.js.map +0 -1
- package/dist/http/SignalInterceptHttpHandler.d.ts +0 -24
- package/dist/http/SignalInterceptHttpHandler.js +0 -47
- package/dist/http/SignalInterceptHttpHandler.js.map +0 -1
- package/dist/http/SignalInterceptHttpHandler.jsonld +0 -103
- package/dist/http/admin/EdgeNodeSignalHttpHandler.d.ts +0 -71
- package/dist/http/admin/EdgeNodeSignalHttpHandler.js +0 -674
- package/dist/http/admin/EdgeNodeSignalHttpHandler.js.map +0 -1
- package/dist/http/admin/EdgeNodeSignalHttpHandler.jsonld +0 -406
- package/dist/http/cluster/PodMigrationHttpHandler.jsonld +0 -169
- package/dist/quota/DefaultQuotaService.d.ts +0 -16
- package/dist/quota/DefaultQuotaService.js +0 -37
- package/dist/quota/DefaultQuotaService.js.map +0 -1
- package/dist/quota/DefaultQuotaService.jsonld +0 -85
- package/dist/service/EdgeNodeHeartbeatService.js.map +0 -1
- package/dist/service/PodMigrationService.jsonld +0 -76
- package/dist/storage/MigratableDataAccessor.d.ts +0 -63
- package/dist/storage/MigratableDataAccessor.js +0 -11
- package/dist/storage/MigratableDataAccessor.js.map +0 -1
- package/dist/storage/MigratableDataAccessor.jsonld +0 -60
- package/dist/storage/accessors/TieredMinioDataAccessor.d.ts +0 -150
- package/dist/storage/accessors/TieredMinioDataAccessor.js +0 -582
- package/dist/storage/accessors/TieredMinioDataAccessor.js.map +0 -1
- package/dist/storage/accessors/TieredMinioDataAccessor.jsonld +0 -333
- package/static/app/assets/index.css +0 -1
- package/static/app/assets/main.js +0 -11
|
@@ -2,10 +2,6 @@ import type { IdentityDatabase } from '../../identity/drizzle/db';
|
|
|
2
2
|
import type { ClientCredentialsRecord, ClientCredentialsStore } from '../auth/ClientCredentialsAuthenticator';
|
|
3
3
|
export interface DrizzleClientCredentialsStoreOptions {
|
|
4
4
|
db: IdentityDatabase;
|
|
5
|
-
/**
|
|
6
|
-
* Encryption key for storing client secrets
|
|
7
|
-
*/
|
|
8
|
-
encryptionKey: string;
|
|
9
5
|
/**
|
|
10
6
|
* Whether using SQLite (default: false for PostgreSQL)
|
|
11
7
|
*/
|
|
@@ -13,19 +9,20 @@ export interface DrizzleClientCredentialsStoreOptions {
|
|
|
13
9
|
}
|
|
14
10
|
/**
|
|
15
11
|
* Storage for API Keys (client credentials) using Drizzle ORM
|
|
12
|
+
*
|
|
13
|
+
* Only stores clientId → webId/accountId mapping.
|
|
14
|
+
* The actual clientSecret lives in the sk-xxx token and is never persisted.
|
|
16
15
|
*/
|
|
17
16
|
export declare class DrizzleClientCredentialsStore implements ClientCredentialsStore {
|
|
18
17
|
private readonly logger;
|
|
19
18
|
private readonly db;
|
|
20
|
-
private readonly encryptionKey;
|
|
21
19
|
private readonly apiClientCredentials;
|
|
22
20
|
constructor(options: DrizzleClientCredentialsStoreOptions);
|
|
23
21
|
/**
|
|
24
|
-
* Store
|
|
22
|
+
* Store API Key registration (called when user creates API Key via frontend)
|
|
25
23
|
*/
|
|
26
24
|
store(options: {
|
|
27
25
|
clientId: string;
|
|
28
|
-
clientSecret: string;
|
|
29
26
|
webId: string;
|
|
30
27
|
accountId: string;
|
|
31
28
|
displayName?: string;
|
|
@@ -35,7 +32,7 @@ export declare class DrizzleClientCredentialsStore implements ClientCredentialsS
|
|
|
35
32
|
*/
|
|
36
33
|
findByClientId(clientId: string): Promise<ClientCredentialsRecord | undefined>;
|
|
37
34
|
/**
|
|
38
|
-
* List API Keys for an account
|
|
35
|
+
* List API Keys for an account
|
|
39
36
|
*/
|
|
40
37
|
listByAccount(accountId: string): Promise<Array<{
|
|
41
38
|
clientId: string;
|
|
@@ -44,13 +41,11 @@ export declare class DrizzleClientCredentialsStore implements ClientCredentialsS
|
|
|
44
41
|
createdAt: Date;
|
|
45
42
|
}>>;
|
|
46
43
|
/**
|
|
47
|
-
* Find the most recently created API Key for an account
|
|
44
|
+
* Find the most recently created API Key for an account.
|
|
48
45
|
*/
|
|
49
46
|
findByAccountId(accountId: string): Promise<ClientCredentialsRecord | undefined>;
|
|
50
47
|
/**
|
|
51
48
|
* Delete an API Key
|
|
52
49
|
*/
|
|
53
50
|
delete(clientId: string, accountId?: string): Promise<boolean>;
|
|
54
|
-
private encrypt;
|
|
55
|
-
private decrypt;
|
|
56
51
|
}
|
|
@@ -1,32 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DrizzleClientCredentialsStore = void 0;
|
|
4
|
-
const node_crypto_1 = require("node:crypto");
|
|
5
4
|
const drizzle_orm_1 = require("drizzle-orm");
|
|
6
5
|
const global_logger_factory_1 = require("global-logger-factory");
|
|
7
6
|
const schema_pg_1 = require("../../identity/drizzle/schema.pg");
|
|
8
7
|
const schema_sqlite_1 = require("../../identity/drizzle/schema.sqlite");
|
|
9
8
|
/**
|
|
10
9
|
* Storage for API Keys (client credentials) using Drizzle ORM
|
|
10
|
+
*
|
|
11
|
+
* Only stores clientId → webId/accountId mapping.
|
|
12
|
+
* The actual clientSecret lives in the sk-xxx token and is never persisted.
|
|
11
13
|
*/
|
|
12
14
|
class DrizzleClientCredentialsStore {
|
|
13
15
|
constructor(options) {
|
|
14
16
|
this.logger = (0, global_logger_factory_1.getLoggerFor)(this);
|
|
15
17
|
this.db = options.db;
|
|
16
|
-
this.encryptionKey = (0, node_crypto_1.scryptSync)(options.encryptionKey, 'xpod-api-salt', 32);
|
|
17
|
-
// Select appropriate schema based on database type
|
|
18
18
|
this.apiClientCredentials = options.isSqlite ? schema_sqlite_1.apiClientCredentials : schema_pg_1.apiClientCredentials;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
|
-
* Store
|
|
21
|
+
* Store API Key registration (called when user creates API Key via frontend)
|
|
22
22
|
*/
|
|
23
23
|
async store(options) {
|
|
24
|
-
const encryptedSecret = this.encrypt(options.clientSecret);
|
|
25
24
|
await this.db
|
|
26
25
|
.insert(this.apiClientCredentials)
|
|
27
26
|
.values({
|
|
28
27
|
clientId: options.clientId,
|
|
29
|
-
clientSecretEncrypted: encryptedSecret,
|
|
30
28
|
webId: options.webId,
|
|
31
29
|
accountId: options.accountId,
|
|
32
30
|
displayName: options.displayName ?? null,
|
|
@@ -34,7 +32,6 @@ class DrizzleClientCredentialsStore {
|
|
|
34
32
|
.onConflictDoUpdate({
|
|
35
33
|
target: this.apiClientCredentials.clientId,
|
|
36
34
|
set: {
|
|
37
|
-
clientSecretEncrypted: encryptedSecret,
|
|
38
35
|
displayName: options.displayName ?? null,
|
|
39
36
|
},
|
|
40
37
|
});
|
|
@@ -55,7 +52,6 @@ class DrizzleClientCredentialsStore {
|
|
|
55
52
|
const row = rows[0];
|
|
56
53
|
return {
|
|
57
54
|
clientId: row.clientId,
|
|
58
|
-
clientSecret: this.decrypt(row.clientSecretEncrypted),
|
|
59
55
|
webId: row.webId,
|
|
60
56
|
accountId: row.accountId,
|
|
61
57
|
displayName: row.displayName ?? undefined,
|
|
@@ -63,7 +59,7 @@ class DrizzleClientCredentialsStore {
|
|
|
63
59
|
};
|
|
64
60
|
}
|
|
65
61
|
/**
|
|
66
|
-
* List API Keys for an account
|
|
62
|
+
* List API Keys for an account
|
|
67
63
|
*/
|
|
68
64
|
async listByAccount(accountId) {
|
|
69
65
|
const rows = await this.db
|
|
@@ -84,7 +80,7 @@ class DrizzleClientCredentialsStore {
|
|
|
84
80
|
}));
|
|
85
81
|
}
|
|
86
82
|
/**
|
|
87
|
-
* Find the most recently created API Key for an account
|
|
83
|
+
* Find the most recently created API Key for an account.
|
|
88
84
|
*/
|
|
89
85
|
async findByAccountId(accountId) {
|
|
90
86
|
const rows = await this.db
|
|
@@ -99,7 +95,6 @@ class DrizzleClientCredentialsStore {
|
|
|
99
95
|
const row = rows[0];
|
|
100
96
|
return {
|
|
101
97
|
clientId: row.clientId,
|
|
102
|
-
clientSecret: this.decrypt(row.clientSecretEncrypted),
|
|
103
98
|
webId: row.webId,
|
|
104
99
|
accountId: row.accountId,
|
|
105
100
|
displayName: row.displayName ?? undefined,
|
|
@@ -110,36 +105,11 @@ class DrizzleClientCredentialsStore {
|
|
|
110
105
|
* Delete an API Key
|
|
111
106
|
*/
|
|
112
107
|
async delete(clientId, accountId) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
.where((0, drizzle_orm_1.eq)(this.apiClientCredentials.clientId, clientId));
|
|
117
|
-
// Check if the deleted row belonged to the account
|
|
118
|
-
// For safety, we could add an AND condition, but Drizzle doesn't support multiple where easily
|
|
119
|
-
// So we trust the caller to verify ownership before calling delete
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
await this.db
|
|
123
|
-
.delete(this.apiClientCredentials)
|
|
124
|
-
.where((0, drizzle_orm_1.eq)(this.apiClientCredentials.clientId, clientId));
|
|
125
|
-
}
|
|
108
|
+
await this.db
|
|
109
|
+
.delete(this.apiClientCredentials)
|
|
110
|
+
.where((0, drizzle_orm_1.eq)(this.apiClientCredentials.clientId, clientId));
|
|
126
111
|
return true;
|
|
127
112
|
}
|
|
128
|
-
encrypt(plaintext) {
|
|
129
|
-
const iv = (0, node_crypto_1.randomBytes)(16);
|
|
130
|
-
const cipher = (0, node_crypto_1.createCipheriv)('aes-256-cbc', this.encryptionKey, iv);
|
|
131
|
-
let encrypted = cipher.update(plaintext, 'utf8', 'hex');
|
|
132
|
-
encrypted += cipher.final('hex');
|
|
133
|
-
return iv.toString('hex') + ':' + encrypted;
|
|
134
|
-
}
|
|
135
|
-
decrypt(ciphertext) {
|
|
136
|
-
const [ivHex, encrypted] = ciphertext.split(':');
|
|
137
|
-
const iv = Buffer.from(ivHex, 'hex');
|
|
138
|
-
const decipher = (0, node_crypto_1.createDecipheriv)('aes-256-cbc', this.encryptionKey, iv);
|
|
139
|
-
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
|
|
140
|
-
decrypted += decipher.final('utf8');
|
|
141
|
-
return decrypted;
|
|
142
|
-
}
|
|
143
113
|
}
|
|
144
114
|
exports.DrizzleClientCredentialsStore = DrizzleClientCredentialsStore;
|
|
145
115
|
//# sourceMappingURL=DrizzleClientCredentialsStore.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DrizzleClientCredentialsStore.js","sourceRoot":"","sources":["../../../src/api/store/DrizzleClientCredentialsStore.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomBytes, createCipheriv, createDecipheriv, scryptSync } from 'node:crypto';\nimport { eq, sql } from 'drizzle-orm';\nimport { getLoggerFor } from 'global-logger-factory';\nimport type { IdentityDatabase } from '../../identity/drizzle/db';\nimport { apiClientCredentials as pgApiClientCredentials } from '../../identity/drizzle/schema.pg';\nimport { apiClientCredentials as sqliteApiClientCredentials } from '../../identity/drizzle/schema.sqlite';\nimport type { ClientCredentialsRecord, ClientCredentialsStore } from '../auth/ClientCredentialsAuthenticator';\n\nexport interface DrizzleClientCredentialsStoreOptions {\n db: IdentityDatabase;\n /**\n * Encryption key for storing client secrets\n */\n encryptionKey: string;\n /**\n * Whether using SQLite (default: false for PostgreSQL)\n */\n isSqlite?: boolean;\n}\n\n/**\n * Storage for API Keys (client credentials) using Drizzle ORM\n */\nexport class DrizzleClientCredentialsStore implements ClientCredentialsStore {\n private readonly logger = getLoggerFor(this);\n private readonly db: IdentityDatabase;\n private readonly encryptionKey: Buffer;\n private readonly apiClientCredentials: typeof pgApiClientCredentials | typeof sqliteApiClientCredentials;\n\n public constructor(options: DrizzleClientCredentialsStoreOptions) {\n this.db = options.db;\n this.encryptionKey = scryptSync(options.encryptionKey, 'xpod-api-salt', 32);\n // Select appropriate schema based on database type\n this.apiClientCredentials = options.isSqlite ? sqliteApiClientCredentials : pgApiClientCredentials;\n }\n\n /**\n * Store client credentials (called when user creates API Key via frontend)\n */\n public async store(options: {\n clientId: string;\n clientSecret: string;\n webId: string;\n accountId: string;\n displayName?: string;\n }): Promise<void> {\n const encryptedSecret = this.encrypt(options.clientSecret);\n\n await this.db\n .insert(this.apiClientCredentials)\n .values({\n clientId: options.clientId,\n clientSecretEncrypted: encryptedSecret,\n webId: options.webId,\n accountId: options.accountId,\n displayName: options.displayName ?? null,\n })\n .onConflictDoUpdate({\n target: this.apiClientCredentials.clientId,\n set: {\n clientSecretEncrypted: encryptedSecret,\n displayName: options.displayName ?? null,\n },\n });\n\n this.logger.info(`Stored API Key: ${options.clientId}`);\n }\n\n /**\n * Find by client_id (the \"API Key\")\n */\n public async findByClientId(clientId: string): Promise<ClientCredentialsRecord | undefined> {\n const rows = await this.db\n .select()\n .from(this.apiClientCredentials)\n .where(eq(this.apiClientCredentials.clientId, clientId))\n .limit(1);\n\n if (rows.length === 0) {\n return undefined;\n }\n\n const row = rows[0];\n return {\n clientId: row.clientId,\n clientSecret: this.decrypt(row.clientSecretEncrypted),\n webId: row.webId,\n accountId: row.accountId,\n displayName: row.displayName ?? undefined,\n createdAt: row.createdAt,\n };\n }\n\n /**\n * List API Keys for an account (without secrets)\n */\n public async listByAccount(accountId: string): Promise<Array<{\n clientId: string;\n webId: string;\n displayName?: string;\n createdAt: Date;\n }>> {\n const rows = await this.db\n .select({\n clientId: this.apiClientCredentials.clientId,\n webId: this.apiClientCredentials.webId,\n displayName: this.apiClientCredentials.displayName,\n createdAt: this.apiClientCredentials.createdAt,\n })\n .from(this.apiClientCredentials)\n .where(eq(this.apiClientCredentials.accountId, accountId))\n .orderBy(sql`${this.apiClientCredentials.createdAt} DESC`);\n\n return rows.map((row: typeof rows[number]) => ({\n clientId: row.clientId,\n webId: row.webId,\n displayName: row.displayName ?? undefined,\n createdAt: row.createdAt,\n }));\n }\n\n /**\n * Find the most recently created API Key for an account (including secret).\n */\n public async findByAccountId(accountId: string): Promise<ClientCredentialsRecord | undefined> {\n const rows = await this.db\n .select()\n .from(this.apiClientCredentials)\n .where(eq(this.apiClientCredentials.accountId, accountId))\n .orderBy(sql`${this.apiClientCredentials.createdAt} DESC`)\n .limit(1);\n\n if (rows.length === 0) {\n return undefined;\n }\n\n const row = rows[0];\n return {\n clientId: row.clientId,\n clientSecret: this.decrypt(row.clientSecretEncrypted),\n webId: row.webId,\n accountId: row.accountId,\n displayName: row.displayName ?? undefined,\n createdAt: row.createdAt,\n };\n }\n\n /**\n * Delete an API Key\n */\n public async delete(clientId: string, accountId?: string): Promise<boolean> {\n if (accountId) {\n const result = await this.db\n .delete(this.apiClientCredentials)\n .where(eq(this.apiClientCredentials.clientId, clientId));\n // Check if the deleted row belonged to the account\n // For safety, we could add an AND condition, but Drizzle doesn't support multiple where easily\n // So we trust the caller to verify ownership before calling delete\n } else {\n await this.db\n .delete(this.apiClientCredentials)\n .where(eq(this.apiClientCredentials.clientId, clientId));\n }\n return true;\n }\n\n private encrypt(plaintext: string): string {\n const iv = randomBytes(16);\n const cipher = createCipheriv('aes-256-cbc', this.encryptionKey, iv);\n let encrypted = cipher.update(plaintext, 'utf8', 'hex');\n encrypted += cipher.final('hex');\n return iv.toString('hex') + ':' + encrypted;\n }\n\n private decrypt(ciphertext: string): string {\n const [ivHex, encrypted] = ciphertext.split(':');\n const iv = Buffer.from(ivHex, 'hex');\n const decipher = createDecipheriv('aes-256-cbc', this.encryptionKey, iv);\n let decrypted = decipher.update(encrypted, 'hex', 'utf8');\n decrypted += decipher.final('utf8');\n return decrypted;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"DrizzleClientCredentialsStore.js","sourceRoot":"","sources":["../../../src/api/store/DrizzleClientCredentialsStore.ts"],"names":[],"mappings":";;;AAAA,6CAAsC;AACtC,iEAAqD;AAErD,gEAAkG;AAClG,wEAA0G;AAW1G;;;;;GAKG;AACH,MAAa,6BAA6B;IAKxC,YAAmB,OAA6C;QAJ/C,WAAM,GAAG,IAAA,oCAAY,EAAC,IAAI,CAAC,CAAC;QAK3C,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;QACrB,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,oCAA0B,CAAC,CAAC,CAAC,gCAAsB,CAAC;IACrG,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,KAAK,CAAC,OAKlB;QACC,MAAM,IAAI,CAAC,EAAE;aACV,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC;aACjC,MAAM,CAAC;YACN,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI;SACzC,CAAC;aACD,kBAAkB,CAAC;YAClB,MAAM,EAAE,IAAI,CAAC,oBAAoB,CAAC,QAAQ;YAC1C,GAAG,EAAE;gBACH,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI;aACzC;SACF,CAAC,CAAC;QAEL,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,cAAc,CAAC,QAAgB;QAC1C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,EAAE;aACvB,MAAM,EAAE;aACR,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC;aAC/B,KAAK,CAAC,IAAA,gBAAE,EAAC,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;aACvD,KAAK,CAAC,CAAC,CAAC,CAAC;QAEZ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,OAAO;YACL,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,SAAS;YACzC,SAAS,EAAE,GAAG,CAAC,SAAS;SACzB,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,aAAa,CAAC,SAAiB;QAM1C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,EAAE;aACvB,MAAM,CAAC;YACN,QAAQ,EAAE,IAAI,CAAC,oBAAoB,CAAC,QAAQ;YAC5C,KAAK,EAAE,IAAI,CAAC,oBAAoB,CAAC,KAAK;YACtC,WAAW,EAAE,IAAI,CAAC,oBAAoB,CAAC,WAAW;YAClD,SAAS,EAAE,IAAI,CAAC,oBAAoB,CAAC,SAAS;SAC/C,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC;aAC/B,KAAK,CAAC,IAAA,gBAAE,EAAC,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;aACzD,OAAO,CAAC,IAAA,iBAAG,EAAA,GAAG,IAAI,CAAC,oBAAoB,CAAC,SAAS,OAAO,CAAC,CAAC;QAE7D,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAwB,EAAE,EAAE,CAAC,CAAC;YAC7C,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,SAAS;YACzC,SAAS,EAAE,GAAG,CAAC,SAAS;SACzB,CAAC,CAAC,CAAC;IACN,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,eAAe,CAAC,SAAiB;QAC5C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,EAAE;aACvB,MAAM,EAAE;aACR,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC;aAC/B,KAAK,CAAC,IAAA,gBAAE,EAAC,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;aACzD,OAAO,CAAC,IAAA,iBAAG,EAAA,GAAG,IAAI,CAAC,oBAAoB,CAAC,SAAS,OAAO,CAAC;aACzD,KAAK,CAAC,CAAC,CAAC,CAAC;QAEZ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,OAAO;YACL,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,SAAS;YACzC,SAAS,EAAE,GAAG,CAAC,SAAS;SACzB,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,MAAM,CAAC,QAAgB,EAAE,SAAkB;QACtD,MAAM,IAAI,CAAC,EAAE;aACV,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC;aACjC,KAAK,CAAC,IAAA,gBAAE,EAAC,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AA3HD,sEA2HC","sourcesContent":["import { eq, sql } from 'drizzle-orm';\nimport { getLoggerFor } from 'global-logger-factory';\nimport type { IdentityDatabase } from '../../identity/drizzle/db';\nimport { apiClientCredentials as pgApiClientCredentials } from '../../identity/drizzle/schema.pg';\nimport { apiClientCredentials as sqliteApiClientCredentials } from '../../identity/drizzle/schema.sqlite';\nimport type { ClientCredentialsRecord, ClientCredentialsStore } from '../auth/ClientCredentialsAuthenticator';\n\nexport interface DrizzleClientCredentialsStoreOptions {\n db: IdentityDatabase;\n /**\n * Whether using SQLite (default: false for PostgreSQL)\n */\n isSqlite?: boolean;\n}\n\n/**\n * Storage for API Keys (client credentials) using Drizzle ORM\n *\n * Only stores clientId → webId/accountId mapping.\n * The actual clientSecret lives in the sk-xxx token and is never persisted.\n */\nexport class DrizzleClientCredentialsStore implements ClientCredentialsStore {\n private readonly logger = getLoggerFor(this);\n private readonly db: IdentityDatabase;\n private readonly apiClientCredentials: typeof pgApiClientCredentials | typeof sqliteApiClientCredentials;\n\n public constructor(options: DrizzleClientCredentialsStoreOptions) {\n this.db = options.db;\n this.apiClientCredentials = options.isSqlite ? sqliteApiClientCredentials : pgApiClientCredentials;\n }\n\n /**\n * Store API Key registration (called when user creates API Key via frontend)\n */\n public async store(options: {\n clientId: string;\n webId: string;\n accountId: string;\n displayName?: string;\n }): Promise<void> {\n await this.db\n .insert(this.apiClientCredentials)\n .values({\n clientId: options.clientId,\n webId: options.webId,\n accountId: options.accountId,\n displayName: options.displayName ?? null,\n })\n .onConflictDoUpdate({\n target: this.apiClientCredentials.clientId,\n set: {\n displayName: options.displayName ?? null,\n },\n });\n\n this.logger.info(`Stored API Key: ${options.clientId}`);\n }\n\n /**\n * Find by client_id (the \"API Key\")\n */\n public async findByClientId(clientId: string): Promise<ClientCredentialsRecord | undefined> {\n const rows = await this.db\n .select()\n .from(this.apiClientCredentials)\n .where(eq(this.apiClientCredentials.clientId, clientId))\n .limit(1);\n\n if (rows.length === 0) {\n return undefined;\n }\n\n const row = rows[0];\n return {\n clientId: row.clientId,\n webId: row.webId,\n accountId: row.accountId,\n displayName: row.displayName ?? undefined,\n createdAt: row.createdAt,\n };\n }\n\n /**\n * List API Keys for an account\n */\n public async listByAccount(accountId: string): Promise<Array<{\n clientId: string;\n webId: string;\n displayName?: string;\n createdAt: Date;\n }>> {\n const rows = await this.db\n .select({\n clientId: this.apiClientCredentials.clientId,\n webId: this.apiClientCredentials.webId,\n displayName: this.apiClientCredentials.displayName,\n createdAt: this.apiClientCredentials.createdAt,\n })\n .from(this.apiClientCredentials)\n .where(eq(this.apiClientCredentials.accountId, accountId))\n .orderBy(sql`${this.apiClientCredentials.createdAt} DESC`);\n\n return rows.map((row: typeof rows[number]) => ({\n clientId: row.clientId,\n webId: row.webId,\n displayName: row.displayName ?? undefined,\n createdAt: row.createdAt,\n }));\n }\n\n /**\n * Find the most recently created API Key for an account.\n */\n public async findByAccountId(accountId: string): Promise<ClientCredentialsRecord | undefined> {\n const rows = await this.db\n .select()\n .from(this.apiClientCredentials)\n .where(eq(this.apiClientCredentials.accountId, accountId))\n .orderBy(sql`${this.apiClientCredentials.createdAt} DESC`)\n .limit(1);\n\n if (rows.length === 0) {\n return undefined;\n }\n\n const row = rows[0];\n return {\n clientId: row.clientId,\n webId: row.webId,\n accountId: row.accountId,\n displayName: row.displayName ?? undefined,\n createdAt: row.createdAt,\n };\n }\n\n /**\n * Delete an API Key\n */\n public async delete(clientId: string, accountId?: string): Promise<boolean> {\n await this.db\n .delete(this.apiClientCredentials)\n .where(eq(this.apiClientCredentials.clientId, clientId));\n return true;\n }\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AsyncHandler } from 'asynchronous-handlers';
|
|
2
|
+
import type { PermissionReader, PermissionReaderInput } from '@solid/community-server';
|
|
3
|
+
export declare class AuthModeSelector extends AsyncHandler<any, any> implements PermissionReader {
|
|
4
|
+
private readonly authMode;
|
|
5
|
+
private readonly acpReader;
|
|
6
|
+
private readonly aclReader;
|
|
7
|
+
private readonly allowAllReader;
|
|
8
|
+
constructor(authMode: string, acpReader: PermissionReader, aclReader: PermissionReader);
|
|
9
|
+
handle(input: PermissionReaderInput): Promise<any>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AuthModeSelector = void 0;
|
|
4
|
+
const asynchronous_handlers_1 = require("asynchronous-handlers");
|
|
5
|
+
const community_server_1 = require("@solid/community-server");
|
|
6
|
+
class AuthModeSelector extends asynchronous_handlers_1.AsyncHandler {
|
|
7
|
+
constructor(authMode, acpReader, aclReader) {
|
|
8
|
+
super();
|
|
9
|
+
this.authMode = authMode || 'acp';
|
|
10
|
+
this.acpReader = acpReader;
|
|
11
|
+
this.aclReader = aclReader;
|
|
12
|
+
this.allowAllReader = new community_server_1.AllStaticReader(true);
|
|
13
|
+
}
|
|
14
|
+
async handle(input) {
|
|
15
|
+
switch (this.authMode) {
|
|
16
|
+
case 'allow-all':
|
|
17
|
+
return this.allowAllReader.handle(input);
|
|
18
|
+
case 'acl':
|
|
19
|
+
return this.aclReader.handle(input);
|
|
20
|
+
case 'acp':
|
|
21
|
+
default:
|
|
22
|
+
return this.acpReader.handle(input);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.AuthModeSelector = AuthModeSelector;
|
|
27
|
+
//# sourceMappingURL=AuthModeSelector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthModeSelector.js","sourceRoot":"","sources":["../../src/authorization/AuthModeSelector.ts"],"names":[],"mappings":";;;AAAA,iEAAqD;AAErD,8DAA0D;AAE1D,MAAa,gBAAiB,SAAQ,oCAAsB;IAM1D,YACE,QAAgB,EAChB,SAA2B,EAC3B,SAA2B;QAE3B,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,QAAQ,GAAG,QAAQ,IAAI,KAAK,CAAC;QAClC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,cAAc,GAAG,IAAI,kCAAe,CAAC,IAAI,CAAC,CAAC;IAClD,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,KAA4B;QAC9C,QAAQ,IAAI,CAAC,QAAQ,EAAE,CAAC;YACtB,KAAK,WAAW;gBACd,OAAO,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC3C,KAAK,KAAK;gBACR,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACtC,KAAK,KAAK,CAAC;YACX;gBACE,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;CACF;AA7BD,4CA6BC","sourcesContent":["import { AsyncHandler } from 'asynchronous-handlers';\nimport type { PermissionReader, PermissionReaderInput, MultiPermissionMap } from '@solid/community-server';\nimport { AllStaticReader } from '@solid/community-server';\n\nexport class AuthModeSelector extends AsyncHandler<any, any> implements PermissionReader {\n private readonly authMode: string;\n private readonly acpReader: PermissionReader;\n private readonly aclReader: PermissionReader;\n private readonly allowAllReader: PermissionReader;\n\n public constructor(\n authMode: string,\n acpReader: PermissionReader,\n aclReader: PermissionReader,\n ) {\n super();\n this.authMode = authMode || 'acp';\n this.acpReader = acpReader;\n this.aclReader = aclReader;\n this.allowAllReader = new AllStaticReader(true);\n }\n\n public async handle(input: PermissionReaderInput): Promise<any> {\n switch (this.authMode) {\n case 'allow-all':\n return this.allowAllReader.handle(input);\n case 'acl':\n return this.aclReader.handle(input);\n case 'acp':\n default:\n return this.acpReader.handle(input);\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"@context": [
|
|
3
|
+
"https://linkedsoftwaredependencies.org/bundles/npm/@undefineds.co/xpod/^0.0.0/components/context.jsonld",
|
|
4
|
+
"https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^8.0.0/components/context.jsonld",
|
|
5
|
+
"https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld"
|
|
6
|
+
],
|
|
7
|
+
"@id": "npmd:@undefineds.co/xpod",
|
|
8
|
+
"components": [
|
|
9
|
+
{
|
|
10
|
+
"@id": "undefineds:dist/authorization/AuthModeSelector.jsonld#AuthModeSelector",
|
|
11
|
+
"@type": "Class",
|
|
12
|
+
"requireElement": "AuthModeSelector",
|
|
13
|
+
"extends": [
|
|
14
|
+
{
|
|
15
|
+
"@type": "GenericComponentExtension",
|
|
16
|
+
"component": "ah:dist/AsyncHandler.jsonld#AsyncHandler",
|
|
17
|
+
"genericTypeInstances": [
|
|
18
|
+
{
|
|
19
|
+
"@type": "ParameterRangeWildcard"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"@type": "ParameterRangeWildcard"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
"css:dist/authorization/PermissionReader.jsonld#PermissionReader"
|
|
27
|
+
],
|
|
28
|
+
"parameters": [
|
|
29
|
+
{
|
|
30
|
+
"@id": "undefineds:dist/authorization/AuthModeSelector.jsonld#AuthModeSelector_authMode",
|
|
31
|
+
"range": "xsd:string"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"@id": "undefineds:dist/authorization/AuthModeSelector.jsonld#AuthModeSelector_acpReader",
|
|
35
|
+
"range": "css:dist/authorization/PermissionReader.jsonld#PermissionReader"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"@id": "undefineds:dist/authorization/AuthModeSelector.jsonld#AuthModeSelector_aclReader",
|
|
39
|
+
"range": "css:dist/authorization/PermissionReader.jsonld#PermissionReader"
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"memberFields": [
|
|
43
|
+
{
|
|
44
|
+
"@id": "undefineds:dist/authorization/AuthModeSelector.jsonld#AuthModeSelector__member_authMode",
|
|
45
|
+
"memberFieldName": "authMode"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"@id": "undefineds:dist/authorization/AuthModeSelector.jsonld#AuthModeSelector__member_acpReader",
|
|
49
|
+
"memberFieldName": "acpReader"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"@id": "undefineds:dist/authorization/AuthModeSelector.jsonld#AuthModeSelector__member_aclReader",
|
|
53
|
+
"memberFieldName": "aclReader"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"@id": "undefineds:dist/authorization/AuthModeSelector.jsonld#AuthModeSelector__member_allowAllReader",
|
|
57
|
+
"memberFieldName": "allowAllReader"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"@id": "undefineds:dist/authorization/AuthModeSelector.jsonld#AuthModeSelector__member_constructor",
|
|
61
|
+
"memberFieldName": "constructor"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"@id": "undefineds:dist/authorization/AuthModeSelector.jsonld#AuthModeSelector__member_handle",
|
|
65
|
+
"memberFieldName": "handle"
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
"constructorArguments": [
|
|
69
|
+
{
|
|
70
|
+
"@id": "undefineds:dist/authorization/AuthModeSelector.jsonld#AuthModeSelector_authMode"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"@id": "undefineds:dist/authorization/AuthModeSelector.jsonld#AuthModeSelector_acpReader"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"@id": "undefineds:dist/authorization/AuthModeSelector.jsonld#AuthModeSelector_aclReader"
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
]
|
|
81
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.accountCommand = void 0;
|
|
4
|
+
const css_account_1 = require("../lib/css-account");
|
|
5
|
+
const credentials_store_1 = require("../lib/credentials-store");
|
|
6
|
+
function resolveUrl(url, credUrl) {
|
|
7
|
+
const raw = url || credUrl || process.env.CSS_BASE_URL || 'http://localhost:3000';
|
|
8
|
+
return raw.endsWith('/') ? raw : `${raw}/`;
|
|
9
|
+
}
|
|
10
|
+
async function loginOrExit(email, password, baseUrl) {
|
|
11
|
+
if (!email || !password) {
|
|
12
|
+
console.error('This command requires --email and --password.');
|
|
13
|
+
console.error('Account management commands use the CSS Account API which requires email/password authentication.');
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
if (!(await (0, css_account_1.checkServer)(baseUrl))) {
|
|
17
|
+
console.error(`Cannot reach server at ${baseUrl}`);
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
const token = await (0, css_account_1.login)(email, password, baseUrl);
|
|
21
|
+
if (!token) {
|
|
22
|
+
console.error('Login failed. Check email/password.');
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
return token;
|
|
26
|
+
}
|
|
27
|
+
const accountCreateCommand = {
|
|
28
|
+
command: 'create',
|
|
29
|
+
describe: 'Create a new account (register)',
|
|
30
|
+
builder: (yargs) => yargs
|
|
31
|
+
.option('email', { type: 'string', demandOption: true, description: 'Account email' })
|
|
32
|
+
.option('password', { type: 'string', demandOption: true, description: 'Account password' }),
|
|
33
|
+
handler: async (argv) => {
|
|
34
|
+
const creds = (0, credentials_store_1.loadCredentials)();
|
|
35
|
+
const baseUrl = resolveUrl(argv.url, creds?.url);
|
|
36
|
+
if (!(await (0, css_account_1.checkServer)(baseUrl))) {
|
|
37
|
+
console.error(`Cannot reach server at ${baseUrl}`);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
const res = await fetch(`${baseUrl}.account/login/password/`, {
|
|
41
|
+
method: 'POST',
|
|
42
|
+
headers: {
|
|
43
|
+
'Content-Type': 'application/json',
|
|
44
|
+
Accept: 'application/json',
|
|
45
|
+
},
|
|
46
|
+
body: JSON.stringify({ email: argv.email, password: argv.password }),
|
|
47
|
+
});
|
|
48
|
+
if (!res.ok) {
|
|
49
|
+
const text = await res.text();
|
|
50
|
+
console.error(`Account creation failed: ${res.status} ${text.slice(0, 200)}`);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
const data = (await res.json());
|
|
54
|
+
if (data.authorization) {
|
|
55
|
+
console.log('Account created and logged in.');
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
console.log('Account created.');
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
const accountListCommand = {
|
|
63
|
+
command: 'list',
|
|
64
|
+
describe: 'Show current account info',
|
|
65
|
+
builder: (yargs) => yargs
|
|
66
|
+
.option('email', { type: 'string', description: 'Account email' })
|
|
67
|
+
.option('password', { type: 'string', description: 'Account password' }),
|
|
68
|
+
handler: async (argv) => {
|
|
69
|
+
const creds = (0, credentials_store_1.loadCredentials)();
|
|
70
|
+
const baseUrl = resolveUrl(argv.url, creds?.url);
|
|
71
|
+
const token = await loginOrExit(argv.email, argv.password, baseUrl);
|
|
72
|
+
const data = await (0, css_account_1.getAccountData)(token, baseUrl);
|
|
73
|
+
if (!data) {
|
|
74
|
+
console.error('Failed to get account info.');
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
const podEntries = Object.entries(data.pods);
|
|
78
|
+
const webIdEntries = Object.entries(data.webIds);
|
|
79
|
+
const credEntries = Object.entries(data.clientCredentials);
|
|
80
|
+
console.log('Account info:\n');
|
|
81
|
+
if (podEntries.length > 0) {
|
|
82
|
+
console.log(` Pods (${podEntries.length}):`);
|
|
83
|
+
for (const [url, name] of podEntries) {
|
|
84
|
+
console.log(` ${name} — ${url}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
console.log(' Pods: none');
|
|
89
|
+
}
|
|
90
|
+
if (webIdEntries.length > 0) {
|
|
91
|
+
console.log(`\n WebIDs (${webIdEntries.length}):`);
|
|
92
|
+
for (const [url] of webIdEntries) {
|
|
93
|
+
console.log(` ${url}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (credEntries.length > 0) {
|
|
97
|
+
console.log(`\n Client credentials (${credEntries.length}):`);
|
|
98
|
+
for (const [url, webId] of credEntries) {
|
|
99
|
+
const id = url.split('/').filter(Boolean).pop() ?? url;
|
|
100
|
+
console.log(` ${id} → ${webId}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
exports.accountCommand = {
|
|
106
|
+
command: 'account',
|
|
107
|
+
describe: 'Account management',
|
|
108
|
+
builder: (yargs) => yargs
|
|
109
|
+
.option('url', {
|
|
110
|
+
alias: 'u',
|
|
111
|
+
type: 'string',
|
|
112
|
+
description: 'Server base URL',
|
|
113
|
+
})
|
|
114
|
+
.command(accountCreateCommand)
|
|
115
|
+
.command(accountListCommand)
|
|
116
|
+
.demandCommand(1, 'Please specify an account subcommand'),
|
|
117
|
+
handler: () => { },
|
|
118
|
+
};
|
|
119
|
+
//# sourceMappingURL=account.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account.js","sourceRoot":"","sources":["../../../src/cli/commands/account.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CommandModule } from 'yargs';\nimport {\n checkServer,\n login,\n getAccountData,\n} from '../lib/css-account';\nimport { loadCredentials } from '../lib/credentials-store';\n\ninterface AccountArgs {\n url?: string;\n}\n\ninterface AccountAuthArgs extends AccountArgs {\n email?: string;\n password?: string;\n}\n\nfunction resolveUrl(url?: string, credUrl?: string): string {\n const raw = url || credUrl || process.env.CSS_BASE_URL || 'http://localhost:3000';\n return raw.endsWith('/') ? raw : `${raw}/`;\n}\n\nasync function loginOrExit(email: string | undefined, password: string | undefined, baseUrl: string): Promise<string> {\n if (!email || !password) {\n console.error('This command requires --email and --password.');\n console.error('Account management commands use the CSS Account API which requires email/password authentication.');\n process.exit(1);\n }\n\n if (!(await checkServer(baseUrl))) {\n console.error(`Cannot reach server at ${baseUrl}`);\n process.exit(1);\n }\n\n const token = await login(email, password, baseUrl);\n if (!token) {\n console.error('Login failed. Check email/password.');\n process.exit(1);\n }\n return token;\n}\n\nconst accountCreateCommand: CommandModule<AccountArgs, AccountAuthArgs> = {\n command: 'create',\n describe: 'Create a new account (register)',\n builder: (yargs) =>\n yargs\n .option('email', { type: 'string', demandOption: true, description: 'Account email' })\n .option('password', { type: 'string', demandOption: true, description: 'Account password' }),\n handler: async (argv) => {\n const creds = loadCredentials();\n const baseUrl = resolveUrl(argv.url, creds?.url);\n\n if (!(await checkServer(baseUrl))) {\n console.error(`Cannot reach server at ${baseUrl}`);\n process.exit(1);\n }\n\n const res = await fetch(`${baseUrl}.account/login/password/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n body: JSON.stringify({ email: argv.email, password: argv.password }),\n });\n\n if (!res.ok) {\n const text = await res.text();\n console.error(`Account creation failed: ${res.status} ${text.slice(0, 200)}`);\n process.exit(1);\n }\n\n const data = (await res.json()) as { authorization?: string };\n if (data.authorization) {\n console.log('Account created and logged in.');\n } else {\n console.log('Account created.');\n }\n },\n};\n\nconst accountListCommand: CommandModule<AccountArgs, AccountAuthArgs> = {\n command: 'list',\n describe: 'Show current account info',\n builder: (yargs) =>\n yargs\n .option('email', { type: 'string', description: 'Account email' })\n .option('password', { type: 'string', description: 'Account password' }),\n handler: async (argv) => {\n const creds = loadCredentials();\n const baseUrl = resolveUrl(argv.url, creds?.url);\n const token = await loginOrExit(argv.email, argv.password, baseUrl);\n\n const data = await getAccountData(token, baseUrl);\n if (!data) {\n console.error('Failed to get account info.');\n process.exit(1);\n }\n\n const podEntries = Object.entries(data.pods);\n const webIdEntries = Object.entries(data.webIds);\n const credEntries = Object.entries(data.clientCredentials);\n\n console.log('Account info:\\n');\n\n if (podEntries.length > 0) {\n console.log(` Pods (${podEntries.length}):`);\n for (const [url, name] of podEntries) {\n console.log(` ${name} — ${url}`);\n }\n } else {\n console.log(' Pods: none');\n }\n\n if (webIdEntries.length > 0) {\n console.log(`\\n WebIDs (${webIdEntries.length}):`);\n for (const [url] of webIdEntries) {\n console.log(` ${url}`);\n }\n }\n\n if (credEntries.length > 0) {\n console.log(`\\n Client credentials (${credEntries.length}):`);\n for (const [url, webId] of credEntries) {\n const id = url.split('/').filter(Boolean).pop() ?? url;\n console.log(` ${id} → ${webId}`);\n }\n }\n },\n};\n\nexport const accountCommand: CommandModule<object, AccountArgs> = {\n command: 'account',\n describe: 'Account management',\n builder: (yargs) =>\n yargs\n .option('url', {\n alias: 'u',\n type: 'string',\n description: 'Server base URL',\n })\n .command(accountCreateCommand)\n .command(accountListCommand)\n .demandCommand(1, 'Please specify an account subcommand'),\n handler: () => {},\n};\n"]}
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.authCommand = void 0;
|
|
7
|
-
const fs_1 = __importDefault(require("fs"));
|
|
8
|
-
const path_1 = __importDefault(require("path"));
|
|
9
4
|
const css_account_1 = require("../lib/css-account");
|
|
5
|
+
const credentials_store_1 = require("../lib/credentials-store");
|
|
10
6
|
function resolveUrl(url) {
|
|
11
7
|
const raw = url || process.env.CSS_BASE_URL || 'http://localhost:3000';
|
|
12
8
|
return raw.endsWith('/') ? raw : `${raw}/`;
|
|
@@ -40,7 +36,7 @@ const createCredentialsCommand = {
|
|
|
40
36
|
.option('password', { type: 'string', demandOption: true, description: 'Account password' })
|
|
41
37
|
.option('web-id', { type: 'string', description: 'WebID to bind credentials to' })
|
|
42
38
|
.option('name', { type: 'string', description: 'Credential label' })
|
|
43
|
-
.option('
|
|
39
|
+
.option('output', { type: 'boolean', default: false, description: 'Print credentials to terminal instead of saving to ~/.xpod/' }),
|
|
44
40
|
handler: async (argv) => {
|
|
45
41
|
const baseUrl = resolveUrl(argv.url);
|
|
46
42
|
if (!(await (0, css_account_1.checkServer)(baseUrl))) {
|
|
@@ -90,29 +86,14 @@ const createCredentialsCommand = {
|
|
|
90
86
|
console.log(` client_id: ${cred.id}`);
|
|
91
87
|
console.log(` client_secret: ${cred.secret}`);
|
|
92
88
|
console.log(` webId: ${webId}`);
|
|
93
|
-
if (argv
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
SOLID_CLIENT_SECRET: cred.secret ?? '',
|
|
102
|
-
SOLID_WEBID: webId,
|
|
103
|
-
SOLID_OIDC_ISSUER: baseUrl,
|
|
104
|
-
};
|
|
105
|
-
for (const [key, value] of Object.entries(updates)) {
|
|
106
|
-
const regex = new RegExp(`^${key}=.*$`, 'm');
|
|
107
|
-
if (regex.test(content)) {
|
|
108
|
-
content = content.replace(regex, `${key}=${value}`);
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
content += `\n${key}=${value}`;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
fs_1.default.writeFileSync(envPath, content.trim() + '\n');
|
|
115
|
-
console.log(`\nWritten to ${envPath}`);
|
|
89
|
+
if (!argv.output) {
|
|
90
|
+
(0, credentials_store_1.saveCredentials)({
|
|
91
|
+
url: baseUrl,
|
|
92
|
+
clientId: cred.id,
|
|
93
|
+
clientSecret: cred.secret ?? '',
|
|
94
|
+
webId,
|
|
95
|
+
});
|
|
96
|
+
console.log(`\nSaved to ${(0, credentials_store_1.getConfigPath)().replace('/config.json', '/')}`);
|
|
116
97
|
}
|
|
117
98
|
},
|
|
118
99
|
};
|
|
@@ -174,6 +155,15 @@ const revokeCommand = {
|
|
|
174
155
|
}
|
|
175
156
|
},
|
|
176
157
|
};
|
|
158
|
+
const logoutCommand = {
|
|
159
|
+
command: 'logout',
|
|
160
|
+
describe: 'Remove stored credentials from ~/.xpod/',
|
|
161
|
+
builder: (yargs) => yargs,
|
|
162
|
+
handler: async () => {
|
|
163
|
+
(0, credentials_store_1.clearCredentials)();
|
|
164
|
+
console.log('Credentials removed.');
|
|
165
|
+
},
|
|
166
|
+
};
|
|
177
167
|
exports.authCommand = {
|
|
178
168
|
command: 'auth',
|
|
179
169
|
describe: 'Authentication and credential management',
|
|
@@ -186,6 +176,7 @@ exports.authCommand = {
|
|
|
186
176
|
})
|
|
187
177
|
.command(loginCommand)
|
|
188
178
|
.command(createCredentialsCommand)
|
|
179
|
+
.command(logoutCommand)
|
|
189
180
|
.command(listCommand)
|
|
190
181
|
.command(revokeCommand)
|
|
191
182
|
.demandCommand(1, 'Please specify an auth subcommand'),
|