@ya-accelerators/web-backend-framework 0.0.66 → 0.0.67

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.
@@ -0,0 +1,4 @@
1
+ export declare const corporateServiceAuth: {
2
+ bearer: () => Promise<string>;
3
+ withAuth: <T>(fn: () => Promise<T>) => Promise<T>;
4
+ };
@@ -0,0 +1,95 @@
1
+ import { defaultEnv } from "../env.js";
2
+ import { logger } from "../logger/index.js";
3
+ import { runWithRequestHeaders } from "../request-context/index.js";
4
+ // Consumer-side auth for calling the central corporate-service (the Estonia-entity compliance
5
+ // runtime). Uses AWS → Google Workload Identity Federation: the running AWS identity federates into
6
+ // a Google Workload Identity Pool, impersonates the configured service account, and mints a
7
+ // Google-signed OIDC ID token for the configured audience. The token is cached and forwarded as a
8
+ // Bearer header so the thin per-env dist client reaches corporate-service authenticated. Uniform
9
+ // across dev/stg/prd — the same WIF config yields a real Google id_token that corporate-service
10
+ // verifies against Google's JWKS; only the AWS identity behind the federation differs. The config
11
+ // holds no credential (it points at the pool / provider / SA), so it lives in .env plaintext.
12
+ //
13
+ // The AWS identity is resolved through the AWS SDK credential chain (env / ECS container credential
14
+ // endpoint / EC2 IMDS, with rotation) rather than google-auth-library's built-in IMDS-only source,
15
+ // so federation works on ECS Fargate, where task-role credentials live at the container credential
16
+ // endpoint instead of IMDS.
17
+ const ID_TOKEN_TTL_SEC = 3600;
18
+ const REFRESH_SKEW_MS = 5 * 60 * 1000;
19
+ let cached;
20
+ let inflight;
21
+ let awsCredentialProvider;
22
+ const fetchIdToken = async () => {
23
+ if (defaultEnv.CORPORATE_SERVICE_AUDIENCE === undefined) {
24
+ throw new Error('corporateServiceAuth: CORPORATE_SERVICE_AUDIENCE is not set');
25
+ }
26
+ if (defaultEnv.CORPORATE_SERVICE_WIF_CONFIG_BASE64 === undefined) {
27
+ throw new Error('corporateServiceAuth: CORPORATE_SERVICE_WIF_CONFIG_BASE64 is not set');
28
+ }
29
+ // google-auth-library and the AWS credential provider are dynamically imported so services that
30
+ // never call corporate-service do not load them.
31
+ const { AwsClient, Impersonated } = await import('google-auth-library');
32
+ const { defaultProvider } = await import('@aws-sdk/credential-provider-node');
33
+ const credentialProvider = (awsCredentialProvider ??= defaultProvider());
34
+ const config = JSON.parse(Buffer.from(defaultEnv.CORPORATE_SERVICE_WIF_CONFIG_BASE64, 'base64').toString('utf8'));
35
+ if (config.service_account_impersonation_url === undefined) {
36
+ throw new Error('corporateServiceAuth: WIF config missing service_account_impersonation_url');
37
+ }
38
+ const serviceAccountEmail = config.service_account_impersonation_url.match(/serviceAccounts\/([^/:]+):/)?.[1];
39
+ if (serviceAccountEmail === undefined) {
40
+ throw new Error('corporateServiceAuth: cannot derive service account email from WIF config');
41
+ }
42
+ // Federation-only client (impersonation + the built-in IMDS source stripped); Impersonated below
43
+ // performs the SA impersonation via generateIdToken, for which the federated principal already
44
+ // holds roles/iam.serviceAccountTokenCreator on the SA.
45
+ return {
46
+ token: await new Impersonated({
47
+ sourceClient: new AwsClient({
48
+ ...config,
49
+ service_account_impersonation_url: undefined,
50
+ credential_source: undefined,
51
+ aws_security_credentials_supplier: {
52
+ getAwsRegion: async () => {
53
+ if (defaultEnv.AWS_REGION === undefined) {
54
+ throw new Error('corporateServiceAuth: AWS_REGION is not set');
55
+ }
56
+ return defaultEnv.AWS_REGION;
57
+ },
58
+ getAwsSecurityCredentials: async () => {
59
+ const c = await credentialProvider();
60
+ return { accessKeyId: c.accessKeyId, secretAccessKey: c.secretAccessKey, token: c.sessionToken };
61
+ },
62
+ },
63
+ }),
64
+ targetPrincipal: serviceAccountEmail,
65
+ lifetime: ID_TOKEN_TTL_SEC,
66
+ targetScopes: ['https://www.googleapis.com/auth/cloud-platform'],
67
+ })
68
+ .fetchIdToken(defaultEnv.CORPORATE_SERVICE_AUDIENCE, { includeEmail: true })
69
+ .catch((e) => {
70
+ logger.error('corporate-service-auth', { error: e });
71
+ throw e;
72
+ }),
73
+ // Google id_tokens are valid for ID_TOKEN_TTL_SEC; bearer() refreshes REFRESH_SKEW_MS earlier. Computed
74
+ // after the mint await, so the expiry tracks the token's real `exp` (the sub-second offset is immaterial
75
+ // against the 5-min REFRESH_SKEW_MS).
76
+ expiresAt: (Math.floor(Date.now() / 1000) + ID_TOKEN_TTL_SEC) * 1000,
77
+ };
78
+ };
79
+ const bearer = async () => {
80
+ if (cached !== undefined && Date.now() <= cached.expiresAt - REFRESH_SKEW_MS) {
81
+ return `Bearer ${cached.token}`;
82
+ }
83
+ if (inflight === undefined) {
84
+ inflight = fetchIdToken().finally(() => {
85
+ inflight = undefined;
86
+ });
87
+ }
88
+ cached = await inflight;
89
+ return `Bearer ${cached.token}`;
90
+ };
91
+ export const corporateServiceAuth = {
92
+ bearer,
93
+ withAuth: async (fn) => runWithRequestHeaders({ authorization: await bearer() }, fn),
94
+ };
95
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/corporate-service-auth/index.ts"],"names":[],"mappings":"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"}
package/dist/env.d.ts CHANGED
@@ -17,4 +17,6 @@ export declare const defaultEnv: {
17
17
  DATABASE_NAME?: string | undefined;
18
18
  LOCAL_S3_ENDPOINT?: string | undefined;
19
19
  AWS_REGION?: string | undefined;
20
+ CORPORATE_SERVICE_AUDIENCE?: string | undefined;
21
+ CORPORATE_SERVICE_WIF_CONFIG_BASE64?: string | undefined;
20
22
  };
package/dist/env.js CHANGED
@@ -2,8 +2,8 @@ import { z } from 'zod';
2
2
  import { Util } from "./util/index.js";
3
3
  export const defaultEnv = Util.createEnvProxy(z.object({
4
4
  // common
5
- NODE_ENV: z.enum(['development', 'production']).default('development'),
6
- DEPLOY_ENV: z.enum(['dev', 'stg', 'prd']).default('dev'),
5
+ NODE_ENV: z.enum(['development', 'production']),
6
+ DEPLOY_ENV: z.enum(['dev', 'stg', 'prd']),
7
7
  // When unset, the threshold defaults to debug on local dev and info on stg/prd (see logger).
8
8
  LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).optional(),
9
9
  // general
@@ -14,10 +14,7 @@ export const defaultEnv = Util.createEnvProxy(z.object({
14
14
  DATABASE_USER: z.string().min(1),
15
15
  DATABASE_PASSWORD: z.string().min(1),
16
16
  DATABASE_NAME: z.string().min(1).optional(),
17
- REDIS_CLUSTER: z
18
- .string()
19
- .default('false')
20
- .transform((val) => val === 'true'),
17
+ REDIS_CLUSTER: z.string().transform((val) => val === 'true'),
21
18
  REDIS_HOST: z.string().min(1),
22
19
  REDIS_PORT: z.string().min(1).transform(Number),
23
20
  // package env
@@ -27,6 +24,14 @@ export const defaultEnv = Util.createEnvProxy(z.object({
27
24
  // s3 (object storage) — LOCAL_S3_ENDPOINT points the client at MinIO on dev; both fall back to the AWS resolution chain
28
25
  LOCAL_S3_ENDPOINT: z.string().optional(),
29
26
  AWS_REGION: z.string().optional(),
27
+ // corporate-service consumer auth — only services that call the central corporate-service set these.
28
+ // CORPORATE_SERVICE_WIF_CONFIG_BASE64 is the AWS → Google Workload Identity Federation cred config
29
+ // (no credential inside; .env plaintext). Kept optional with no object-level refine: a non-consumer
30
+ // service must not fail env validation for these. corporateServiceAuth.bearer() fails-closed (throws)
31
+ // at call time when unset; a consumer that wants boot-time validation adds it in its own constants.ts.
32
+ // See corporate-service-auth.
33
+ CORPORATE_SERVICE_AUDIENCE: z.string().optional(),
34
+ CORPORATE_SERVICE_WIF_CONFIG_BASE64: z.string().optional(),
30
35
  }), () => ({
31
36
  // common
32
37
  NODE_ENV: process.env.NODE_ENV,
@@ -50,5 +55,8 @@ export const defaultEnv = Util.createEnvProxy(z.object({
50
55
  // s3 (object storage)
51
56
  LOCAL_S3_ENDPOINT: process.env.LOCAL_S3_ENDPOINT,
52
57
  AWS_REGION: process.env.AWS_REGION,
58
+ // corporate-service consumer auth
59
+ CORPORATE_SERVICE_AUDIENCE: process.env.CORPORATE_SERVICE_AUDIENCE,
60
+ CORPORATE_SERVICE_WIF_CONFIG_BASE64: process.env.CORPORATE_SERVICE_WIF_CONFIG_BASE64,
53
61
  }));
54
62
  //# sourceMappingURL=env.js.map
package/dist/env.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './app/index.ts';
2
2
  export * from './audit-context/index.ts';
3
+ export * from './corporate-service-auth/index.ts';
3
4
  export * from './env.ts';
4
5
  export * from './lock/index.ts';
5
6
  export * from './logger/index.ts';
@@ -9,3 +10,4 @@ export * from './redis/index.ts';
9
10
  export * from './s3/index.ts';
10
11
  export * from './throttle/index.ts';
11
12
  export * from './util/index.ts';
13
+ export * from './worker/index.ts';
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from "./app/index.js";
2
2
  export * from "./audit-context/index.js";
3
+ export * from "./corporate-service-auth/index.js";
3
4
  export * from "./env.js";
4
5
  export * from "./lock/index.js";
5
6
  export * from "./logger/index.js";
@@ -9,4 +10,5 @@ export * from "./redis/index.js";
9
10
  export * from "./s3/index.js";
10
11
  export * from "./throttle/index.js";
11
12
  export * from "./util/index.js";
13
+ export * from "./worker/index.js";
12
14
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,0BAA0B,CAAA;AACxC,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,eAAe,CAAA;AAC7B,cAAc,qBAAqB,CAAA;AACnC,cAAc,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,0BAA0B,CAAA;AACxC,cAAc,mCAAmC,CAAA;AACjD,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,eAAe,CAAA;AAC7B,cAAc,qBAAqB,CAAA;AACnC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,mBAAmB,CAAA"}
package/dist/s3/index.js CHANGED
@@ -59,10 +59,11 @@ const listObjectVersions = async (params) => {
59
59
  return versions;
60
60
  };
61
61
  // Delete versions of a key no longer referenced (`keepVersionIds` = the version-ids still indexed).
62
- // A version still under retention cannot be deleted: S3 rejects it with `AccessDenied`, and it is
63
- // returned in `skippedVersionIds` rather than failing the whole sweep. GOVERNANCE-mode versions
64
- // under retention are deletable only with `governanceBypass` (requires `s3:BypassGovernanceRetention`).
65
- // Any other error propagates — only the retention denial is caught.
62
+ // A version still under retention cannot be deleted: it is returned in `skippedVersionIds` rather than
63
+ // failing the whole sweep. The retention denial surfaces as `AccessDenied` on AWS S3 and as
64
+ // `InvalidRequest` on MinIO (local/dev) — both are treated as "retained, skip". GOVERNANCE-mode
65
+ // versions under retention are deletable only with `governanceBypass` (requires
66
+ // `s3:BypassGovernanceRetention`). Any other error propagates.
66
67
  const deleteOrphanVersions = async (params) => {
67
68
  const keep = new Set(params.keepVersionIds);
68
69
  const deletedVersionIds = [];
@@ -81,7 +82,7 @@ const deleteOrphanVersions = async (params) => {
81
82
  deletedVersionIds.push(version.versionId);
82
83
  }
83
84
  catch (error) {
84
- if (error instanceof Error && error.name === 'AccessDenied') {
85
+ if (error instanceof Error && (error.name === 'AccessDenied' || error.name === 'InvalidRequest')) {
85
86
  skippedVersionIds.push(version.versionId);
86
87
  }
87
88
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/s3/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/s3/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ type PurgeDelegate = {
2
+ findMany: (args: {
3
+ where: Record<string, {
4
+ lt: Date;
5
+ } | {
6
+ gt: string;
7
+ }>;
8
+ select: {
9
+ id: true;
10
+ };
11
+ orderBy: {
12
+ id: 'asc';
13
+ };
14
+ take: number;
15
+ }) => Promise<{
16
+ id: string;
17
+ }[]>;
18
+ deleteMany: (args: {
19
+ where: {
20
+ id: {
21
+ in: string[];
22
+ };
23
+ };
24
+ }) => Promise<{
25
+ count: number;
26
+ }>;
27
+ };
28
+ export type PurgeTarget = {
29
+ delegate: string;
30
+ category: string;
31
+ anchorField: string;
32
+ };
33
+ export declare const retentionPurge: (params: {
34
+ delegateFor: (name: string) => PurgeDelegate | undefined;
35
+ targets: readonly PurgeTarget[];
36
+ cutoffFor: (category: string, now: Date) => Date | null;
37
+ retainIds?: (delegate: string, ids: readonly string[]) => Promise<readonly string[]>;
38
+ now?: Date;
39
+ }) => Promise<void>;
40
+ export type EraseClient = {
41
+ pollErasureRequests: (input: {
42
+ idempotencyKey: string;
43
+ }) => Promise<{
44
+ requestId: string;
45
+ subjectId: string;
46
+ subjectType: string;
47
+ deferReason?: string;
48
+ }[]>;
49
+ reportErasureResult: (input: {
50
+ requestId: string;
51
+ status: 'erased' | 'skipped' | 'deferred' | 'failed';
52
+ anonymizedFields?: string[];
53
+ deferReason?: string;
54
+ error?: {
55
+ code: string;
56
+ message: string;
57
+ };
58
+ idempotencyKey: string;
59
+ }) => Promise<void>;
60
+ };
61
+ type EraseDelegate = {
62
+ deleteMany: (args: {
63
+ where: Record<string, string>;
64
+ }) => Promise<{
65
+ count: number;
66
+ }>;
67
+ updateMany: (args: {
68
+ where: Record<string, string>;
69
+ data: Record<string, null>;
70
+ }) => Promise<{
71
+ count: number;
72
+ }>;
73
+ };
74
+ export type EraseTarget = {
75
+ delegate: string;
76
+ subjectField: string;
77
+ strategy: 'delete-row' | 'anonymize';
78
+ piiFields: readonly string[];
79
+ };
80
+ export declare const erase: (params: {
81
+ client: EraseClient;
82
+ delegateFor: (name: string) => EraseDelegate | undefined;
83
+ targets: readonly EraseTarget[];
84
+ idempotencyKey: () => string;
85
+ }) => Promise<void>;
86
+ export {};
@@ -0,0 +1,98 @@
1
+ import { logger } from "../logger/index.js";
2
+ const PURGE_BATCH = 1000;
3
+ export const retentionPurge = async (params) => {
4
+ const now = params.now ?? new Date();
5
+ for (const target of params.targets) {
6
+ const cutoff = params.cutoffFor(target.category, now);
7
+ if (cutoff === null) {
8
+ continue;
9
+ }
10
+ const delegate = params.delegateFor(target.delegate);
11
+ if (delegate === undefined) {
12
+ logger.error('retention-purge', { delegate: target.delegate, message: 'no matching prisma delegate' });
13
+ continue;
14
+ }
15
+ // Small idempotent id-cursor pages; a null anchor (window not started) is excluded by `lt`.
16
+ let afterId = '';
17
+ for (;;) {
18
+ const rows = await delegate.findMany({
19
+ where: { [target.anchorField]: { lt: cutoff }, id: { gt: afterId } },
20
+ select: { id: true },
21
+ orderBy: { id: 'asc' },
22
+ take: PURGE_BATCH,
23
+ });
24
+ if (rows.length === 0) {
25
+ break;
26
+ }
27
+ afterId = rows[rows.length - 1].id;
28
+ const ids = rows.map((row) => row.id);
29
+ const retained = params.retainIds ? new Set(await params.retainIds(target.delegate, ids)) : undefined;
30
+ const toDelete = retained ? ids.filter((id) => !retained.has(id)) : ids;
31
+ if (toDelete.length > 0) {
32
+ await delegate.deleteMany({ where: { id: { in: toDelete } } });
33
+ }
34
+ }
35
+ }
36
+ };
37
+ export const erase = async (params) => {
38
+ const requests = await params.client.pollErasureRequests({ idempotencyKey: params.idempotencyKey() });
39
+ for (const request of requests) {
40
+ // A subject under an active legal hold is reported `deferred` and left untouched (infra.md § 11);
41
+ // the next cycle re-polls it and erases once the hold is released.
42
+ if (request.deferReason !== undefined) {
43
+ await params.client
44
+ .reportErasureResult({
45
+ requestId: request.requestId,
46
+ status: 'deferred',
47
+ deferReason: request.deferReason,
48
+ idempotencyKey: params.idempotencyKey(),
49
+ })
50
+ .catch((e) => {
51
+ logger.error('erase', { requestId: request.requestId, error: e });
52
+ });
53
+ continue;
54
+ }
55
+ try {
56
+ const anonymizedFields = [];
57
+ let touched = false;
58
+ for (const target of params.targets) {
59
+ const delegate = params.delegateFor(target.delegate);
60
+ if (delegate === undefined) {
61
+ continue;
62
+ }
63
+ if (target.strategy === 'delete-row') {
64
+ const { count } = await delegate.deleteMany({ where: { [target.subjectField]: request.subjectId } });
65
+ touched = touched || count > 0;
66
+ }
67
+ else {
68
+ const { count } = await delegate.updateMany({
69
+ where: { [target.subjectField]: request.subjectId },
70
+ data: Object.fromEntries(target.piiFields.map((field) => [field, null])),
71
+ });
72
+ if (count > 0) {
73
+ touched = true;
74
+ anonymizedFields.push(...target.piiFields);
75
+ }
76
+ }
77
+ }
78
+ await params.client.reportErasureResult({
79
+ requestId: request.requestId,
80
+ status: touched ? 'erased' : 'skipped',
81
+ anonymizedFields: anonymizedFields.length > 0 ? anonymizedFields : undefined,
82
+ idempotencyKey: params.idempotencyKey(),
83
+ });
84
+ }
85
+ catch (e) {
86
+ logger.error('erase', { requestId: request.requestId, error: e });
87
+ await params.client
88
+ .reportErasureResult({
89
+ requestId: request.requestId,
90
+ status: 'failed',
91
+ error: { code: 'erase_failed', message: e instanceof Error ? e.message : 'unknown' },
92
+ idempotencyKey: params.idempotencyKey(),
93
+ })
94
+ .catch(() => undefined);
95
+ }
96
+ }
97
+ };
98
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/worker/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ya-accelerators/web-backend-framework",
3
- "version": "0.0.66",
3
+ "version": "0.0.67",
4
4
  "type": "module",
5
5
  "description": "",
6
6
  "author": "YA Technologies OÜ",
@@ -40,12 +40,15 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@aws-sdk/client-s3": "^3.1048.0",
43
+ "@aws-sdk/credential-provider-node": "^3.972.58",
43
44
  "@prisma/adapter-mariadb": "^7.8.0",
44
45
  "@prisma/extension-read-replicas": "^0.5.0",
45
46
  "@valkey/valkey-glide": "^2.4.0",
46
47
  "cors": "^2.8.6",
47
48
  "express": "^5.2.1",
49
+ "google-auth-library": "^10.9.0",
48
50
  "http-proxy-middleware": "^4.0.0",
51
+ "jose": "^6.2.3",
49
52
  "mariadb": "^3.5.2",
50
53
  "ulid": "^3.0.2"
51
54
  },