From f76673ed3e4e630c84f46b92581addb2353dab6d Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Wed, 9 Jul 2025 10:00:52 +0200 Subject: [PATCH 1/2] Remove unused dev config. --- packages/service-core/src/routes/auth.ts | 125 +----------------- .../util/config/compound-config-collector.ts | 16 --- .../service-core/src/util/config/types.ts | 11 -- packages/types/src/config/PowerSyncConfig.ts | 31 ----- 4 files changed, 1 insertion(+), 182 deletions(-) diff --git a/packages/service-core/src/routes/auth.ts b/packages/service-core/src/routes/auth.ts index 81716b945..f2c5726ab 100644 --- a/packages/service-core/src/routes/auth.ts +++ b/packages/service-core/src/routes/auth.ts @@ -1,10 +1,7 @@ -import * as jose from 'jose'; - +import { AuthorizationError, AuthorizationResponse, ErrorCode } from '@powersync/lib-services-framework'; import * as auth from '../auth/auth-index.js'; import { ServiceContext } from '../system/ServiceContext.js'; -import * as util from '../util/util-index.js'; import { BasicRouterRequest, Context, RequestEndpointHandlerPayload } from './router.js'; -import { AuthorizationError, AuthorizationResponse, ErrorCode, ServiceError } from '@powersync/lib-services-framework'; export function endpoint(req: BasicRouterRequest) { const protocol = req.headers['x-forwarded-proto'] ?? req.protocol; @@ -12,81 +9,6 @@ export function endpoint(req: BasicRouterRequest) { return `${protocol}://${host}`; } -function devAudience(req: BasicRouterRequest): string { - return `${endpoint(req)}/dev`; -} - -/** - * @deprecated - * - * Will be replaced by temporary tokens issued by PowerSync Management service. - */ -export async function issueDevToken(req: BasicRouterRequest, user_id: string, config: util.ResolvedPowerSyncConfig) { - const iss = devAudience(req); - const aud = devAudience(req); - - const key = config.dev.dev_key; - if (key == null) { - throw new Error('Auth disabled'); - } - - return await new jose.SignJWT({}) - .setProtectedHeader({ alg: key.source.alg!, kid: key.kid }) - .setSubject(user_id) - .setIssuedAt() - .setIssuer(iss) - .setAudience(aud) - .setExpirationTime('30d') - .sign(key.key); -} - -/** @deprecated */ -export async function issueLegacyDevToken( - req: BasicRouterRequest, - user_id: string, - config: util.ResolvedPowerSyncConfig -) { - const iss = devAudience(req); - const aud = config.jwt_audiences[0]; - - const key = config.dev.dev_key; - if (key == null || aud == null) { - throw new Error('Auth disabled'); - } - - return await new jose.SignJWT({}) - .setProtectedHeader({ alg: key.source.alg!, kid: key.kid }) - .setSubject(user_id) - .setIssuedAt() - .setIssuer(iss) - .setAudience(aud) - .setExpirationTime('60m') - .sign(key.key); -} - -export async function issuePowerSyncToken( - req: BasicRouterRequest, - user_id: string, - config: util.ResolvedPowerSyncConfig -) { - const iss = devAudience(req); - const aud = config.jwt_audiences[0]; - const key = config.dev.dev_key; - if (key == null || aud == null) { - throw new Error('Auth disabled'); - } - - const jwt = await new jose.SignJWT({}) - .setProtectedHeader({ alg: key.source.alg!, kid: key.kid }) - .setSubject(user_id) - .setIssuedAt() - .setIssuer(iss) - .setAudience(aud) - .setExpirationTime('5m') - .sign(key.key); - return jwt; -} - export function getTokenFromHeader(authHeader: string = ''): string | null { const tokenMatch = /^(Token|Bearer) (\S+)$/.exec(authHeader); if (!tokenMatch) { @@ -146,51 +68,6 @@ export async function generateContext(serviceContext: ServiceContext, token: str } } -/** - * @deprecated - */ -export const authDevUser = async (payload: RequestEndpointHandlerPayload) => { - const { - context: { - service_context: { configuration } - } - } = payload; - - const token = getTokenFromHeader(payload.request.headers.authorization as string); - if (!configuration.dev.demo_auth) { - return { - authorized: false, - errors: ['Authentication disabled'] - }; - } - if (token == null) { - return { - authorized: false, - errors: ['Authentication required'] - }; - } - - // Different from the configured audience. - // Should also not be changed by keys - const audience = [devAudience(payload.request)]; - - let tokenPayload: auth.JwtPayload; - try { - tokenPayload = await configuration.dev_client_keystore.verifyJwt(token, { - defaultAudiences: audience, - maxAge: '31d' - }); - } catch (err) { - return { - authorized: false, - errors: [err.message] - }; - } - - payload.context.user_id = tokenPayload.sub; - return { authorized: true }; -}; - export const authApi = (payload: RequestEndpointHandlerPayload) => { const { context: { diff --git a/packages/service-core/src/util/config/compound-config-collector.ts b/packages/service-core/src/util/config/compound-config-collector.ts index 742800d9b..de485c4b7 100644 --- a/packages/service-core/src/util/config/compound-config-collector.ts +++ b/packages/service-core/src/util/config/compound-config-collector.ts @@ -42,8 +42,6 @@ export type ConfigCollectorListener = { configCollected?: (event: ConfigCollectedEvent) => Promise; }; -const POWERSYNC_DEV_KID = 'powersync-dev'; - const DEFAULT_COLLECTOR_OPTIONS: CompoundConfigCollectorOptions = { configCollectors: [new Base64ConfigCollector(), new FileSystemConfigCollector(), new FallbackConfigCollector()], syncRulesCollectors: [ @@ -117,13 +115,6 @@ export class CompoundConfigCollector { collectors.add(new auth.CachedKeyCollector(new auth.RemoteJWKSCollector(uri, { lookupOptions: jwksLookup }))); } - const baseDevKey = (baseConfig.client_auth?.jwks?.keys ?? []).find((key) => key.kid == POWERSYNC_DEV_KID); - - let devKey: auth.KeySpec | undefined; - if (baseConfig.dev?.demo_auth && baseDevKey != null && baseDevKey.kty == 'oct') { - devKey = await auth.KeySpec.importKey(baseDevKey); - } - const sync_rules = await this.collectSyncRules(baseConfig, runnerConfig); let jwt_audiences: string[] = baseConfig.client_auth?.audience ?? []; @@ -138,14 +129,7 @@ export class CompoundConfigCollector { } }, client_keystore: keyStore, - // Dev tokens only use the static keys, no external key sources - // We may restrict this even further to only the powersync-dev key. - dev_client_keystore: new auth.KeyStore(staticCollector), api_tokens: baseConfig.api?.tokens ?? [], - dev: { - demo_auth: baseConfig.dev?.demo_auth ?? false, - dev_key: devKey - }, port: baseConfig.port ?? 8080, sync_rules, jwt_audiences, diff --git a/packages/service-core/src/util/config/types.ts b/packages/service-core/src/util/config/types.ts index 614b8e2b0..6b8a88b7f 100644 --- a/packages/service-core/src/util/config/types.ts +++ b/packages/service-core/src/util/config/types.ts @@ -32,18 +32,7 @@ export type ResolvedPowerSyncConfig = { base_config: configFile.PowerSyncConfig; connections?: configFile.GenericDataSourceConfig[]; storage: configFile.GenericStorageConfig; - dev: { - demo_auth: boolean; - /** - * Only present when demo_auth == true - */ - dev_key?: KeySpec; - }; client_keystore: KeyStore; - /** - * Keystore for development tokens. - */ - dev_client_keystore: KeyStore; port: number; sync_rules: SyncRulesConfig; api_tokens: string[]; diff --git a/packages/types/src/config/PowerSyncConfig.ts b/packages/types/src/config/PowerSyncConfig.ts index cd9e288ef..0a8288640 100644 --- a/packages/types/src/config/PowerSyncConfig.ts +++ b/packages/types/src/config/PowerSyncConfig.ts @@ -263,37 +263,6 @@ export const powerSyncConfig = t }) .optional(), - dev: t - .object({ - demo_auth: t.boolean - .meta({ - description: 'Enables demo authentication for development purposes.' - }) - .optional(), - /** @deprecated */ - demo_password: t.string - .meta({ - description: 'Deprecated. Demo password for development authentication.' - }) - .optional(), - /** @deprecated */ - crud_api: t.boolean - .meta({ - description: 'Deprecated. Enables CRUD API for development.' - }) - .optional(), - /** @deprecated */ - demo_client: t.boolean - .meta({ - description: 'Deprecated. Enables demo client for development.' - }) - .optional() - }) - .meta({ - description: 'Development-specific configuration options.' - }) - .optional(), - client_auth: t .object({ jwks_uri: t.string From 795ddafe567f9de373477d055a7748436611dcf4 Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Wed, 9 Jul 2025 10:04:37 +0200 Subject: [PATCH 2/2] Add changeset. --- .changeset/stupid-monkeys-think.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/stupid-monkeys-think.md diff --git a/.changeset/stupid-monkeys-think.md b/.changeset/stupid-monkeys-think.md new file mode 100644 index 000000000..2a1c0585d --- /dev/null +++ b/.changeset/stupid-monkeys-think.md @@ -0,0 +1,6 @@ +--- +'@powersync/service-core': patch +'@powersync/service-types': patch +--- + +Remove unused dev config.