Skip to content

Commit 62ab7db

Browse files
authored
feat(token-kiosk): integerated with config-server MAPCO-8124 (#88)
* chore: wip * feat: done with configuration * deps: package lock
1 parent 16093c8 commit 62ab7db

21 files changed

Lines changed: 201 additions & 149 deletions

package-lock.json

Lines changed: 4 additions & 68 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/token-kiosk/config/default.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
"uiPath": "/api"
77
},
88
"telemetry": {
9-
"metrics": {},
109
"tracing": {
1110
"isEnabled": false
1211
},
@@ -33,10 +32,10 @@
3332
"db": {
3433
"host": "localhost",
3534
"port": 5432,
36-
"user": "postgres",
35+
"username": "postgres",
3736
"password": "postgres",
38-
"enableSslAuth": false,
39-
"sslPaths": {
37+
"ssl": {
38+
"enabled": false,
4039
"ca": "",
4140
"key": "",
4241
"cert": ""
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"auth": {
3+
"openid": {
4+
"clientId": "my-local-app",
5+
"issuerBaseUrl": "http://localhost:8080/realms/my-local-realm",
6+
"baseUrl": "http://localhost:5173",
7+
"secret": "sdfsdasdsadsadsadsadsadas",
8+
"clientSecret": "78vaqxyFyyf1xeTHXzgzNlhCVtW83Zi7",
9+
"scopes": "openid profile email",
10+
"idField": "email",
11+
"metadataFields": ["email", "email_verified", "name", "given_name", "family_name", "preferred_username"]
12+
}
13+
},
14+
"token": {
15+
"environment": "prod",
16+
"expirationDuration": "1w",
17+
"domains": ["raster"],
18+
"jwt": {
19+
"subject": "c2b",
20+
"issuer": "token-kiosk",
21+
"algorithm": "RS256"
22+
},
23+
"authManager": {
24+
"baseUrl": "http://localhost:8082",
25+
"cacheTtlHours": 1
26+
}
27+
}
28+
}

packages/token-kiosk/openapi3.yaml

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ paths:
3535
summary: Get current authenticated user information
3636
description: Returns information about the currently authenticated user
3737
security:
38-
- bearerAuth: []
38+
- openid: []
3939
responses:
4040
200:
4141
description: User information retrieved successfully
@@ -51,14 +51,13 @@ paths:
5151
$ref: '#/components/schemas/error'
5252
security:
5353
- {}
54-
- bearerAuth: []
54+
- openid: []
5555
components:
5656
securitySchemes:
57-
bearerAuth:
58-
type: http
59-
scheme: bearer
60-
bearerFormat: JWT
61-
description: Bearer token authentication using JWT access tokens
57+
openid:
58+
type: openIdConnect
59+
openIdConnectUrl: http://localhost:8080/realms/my-local-app/.well-known/openid-configuration
60+
6261
schemas:
6362
error:
6463
type: object
@@ -72,7 +71,6 @@ components:
7271
required:
7372
- token
7473
- expiration
75-
- domains
7674
properties:
7775
token:
7876
type: string
@@ -81,11 +79,6 @@ components:
8179
type: string
8280
format: date-time
8381
description: Expiration date and time of the token
84-
domains:
85-
type: array
86-
items:
87-
type: string
88-
description: List of domains the token is valid for
8982
userInfo:
9083
type: object
9184
required:

packages/token-kiosk/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@
3030
"license": "ISC",
3131
"dependencies": {
3232
"@godaddy/terminus": "^4.12.1",
33-
"@map-colonies/config": "^2.2.0",
33+
"@map-colonies/config": "^3.0.0",
3434
"@map-colonies/error-express-handler": "^3.0.0",
3535
"@map-colonies/express-access-log-middleware": "^3.0.1",
3636
"@map-colonies/js-logger": "^2.0.0",
3737
"@map-colonies/openapi-express-viewer": "^4.0.0",
3838
"@map-colonies/read-pkg": "^1.0.0",
39-
"@map-colonies/schemas": "^1.3.0",
39+
"@map-colonies/schemas": "https://ghatmpstorage.blob.core.windows.net/npm-packages/schemas-bc7a0664630e2a828ddc79244ecae27f4413592d.tgz",
4040
"@map-colonies/telemetry": "^10.0.1",
4141
"@opentelemetry/api": "^1.9.0",
4242
"async-cache-dedupe": "^2.2.0",
Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
11
import { RequestHandler } from 'express';
22
import { auth } from 'express-openid-connect';
3+
import { DependencyContainer } from 'tsyringe';
4+
import { SERVICES } from '@src/common/constants';
5+
import type { ConfigType } from '@src/common/config';
6+
7+
export function openidAuthMiddlewareFactory(container: DependencyContainer): RequestHandler {
8+
const config = container.resolve<ConfigType>(SERVICES.CONFIG);
9+
10+
const authConfig = config.get('auth.openid');
311

4-
export function openidAuthMiddlewareFactory(): RequestHandler {
512
return auth({
6-
clientID: 'my-local-app',
7-
issuerBaseURL: 'http://localhost:8080/realms/my-local-realm',
8-
baseURL: 'http://localhost:5173',
13+
clientID: authConfig.clientId,
14+
issuerBaseURL: authConfig.issuerBaseUrl,
15+
baseURL: authConfig.baseUrl,
916
authRequired: true,
1017
authorizationParams: {
1118
// eslint-disable-next-line @typescript-eslint/naming-convention
1219
response_type: 'code',
13-
scope: 'openid profile email',
20+
scope: authConfig.scopes,
1421
},
15-
secret: 'sdfsdasdsadsadsadsadsadas',
16-
clientSecret: '78vaqxyFyyf1xeTHXzgzNlhCVtW83Zi7',
22+
secret: authConfig.secret,
23+
clientSecret: authConfig.clientSecret,
1724
auth0Logout: false,
1825
});
1926
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { inject, injectable } from 'tsyringe';
2+
import { type Logger } from '@map-colonies/js-logger';
3+
import { type ConfigType } from '@src/common/config';
4+
import { SERVICES } from '@src/common/constants';
5+
6+
@injectable()
7+
export class AuthManager {
8+
public constructor(
9+
@inject(SERVICES.CONFIG) private readonly config: ConfigType,
10+
@inject(SERVICES.LOGGER) private readonly logger: Logger
11+
) {}
12+
13+
public getIdKey(): string {
14+
return this.config.get('auth.openid.idField');
15+
}
16+
17+
public metadataFieldsPicker(userData: Record<string, unknown>): Record<string, unknown> {
18+
const metadataFields = this.config.get('auth.openid.metadataFields');
19+
const result: Record<string, unknown> = {};
20+
21+
for (const field of metadataFields) {
22+
if (field in userData) {
23+
result[field] = userData[field];
24+
} else {
25+
this.logger.warn(`Field '${field}' does not exist in userData`);
26+
}
27+
}
28+
29+
return result;
30+
}
31+
}

packages/token-kiosk/src/common/config.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { type ConfigInstance, config } from '@map-colonies/config';
2-
import { commonBoilerplateV2, type commonBoilerplateV2Type } from '@map-colonies/schemas';
2+
import { infraOpalaTokenKioskV1, type infraOpalaTokenKioskV1Type } from '@map-colonies/schemas';
33

44
// Choose here the type of the config instance and import this type from the entire application
5-
type ConfigType = ConfigInstance<commonBoilerplateV2Type>;
5+
type ConfigType = ConfigInstance<infraOpalaTokenKioskV1Type>;
66

77
let configInstance: ConfigType | undefined;
88

@@ -13,7 +13,7 @@ let configInstance: ConfigType | undefined;
1313
*/
1414
async function initConfig(offlineMode?: boolean): Promise<void> {
1515
configInstance = await config({
16-
schema: commonBoilerplateV2,
16+
schema: infraOpalaTokenKioskV1,
1717
offlineMode,
1818
});
1919
}

packages/token-kiosk/src/common/constants.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { readPackageJsonSync } from '@map-colonies/read-pkg';
33
export const SERVICE_NAME = readPackageJsonSync().name ?? 'unknown_service';
44
export const DEFAULT_SERVER_PORT = 80;
55

6+
export const DB_CONNECTION_TIMEOUT = 5000;
7+
68
export const IGNORED_OUTGOING_TRACE_ROUTES = [/^.*\/v1\/metrics.*$/];
79
export const IGNORED_INCOMING_TRACE_ROUTES = [/^.*\/docs.*$/];
810

@@ -13,7 +15,9 @@ export const SERVICES = {
1315
TRACER: Symbol('Tracer'),
1416
METRICS: Symbol('METRICS'),
1517
AUTH_MANAGER_CLIENT: Symbol('AuthManagerClient'),
18+
AUTH_MIDDLEWARE: Symbol('AuthMiddleware'),
1619
PG_POOL: Symbol('PgPool'),
1720
DRIZZLE: Symbol('Drizzle'),
21+
HEALTHCHECK: Symbol('HealthCheck'),
1822
} satisfies Record<string, symbol>;
1923
/* eslint-enable @typescript-eslint/naming-convention */
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export class TimeoutError extends Error {}
2+
3+
export async function promiseTimeout<T>(ms: number, promise: Promise<T>): Promise<T> {
4+
// Create a promise that rejects in <ms> milliseconds
5+
const timeout = new Promise<T>((_, reject) => {
6+
const id = setTimeout(() => {
7+
clearTimeout(id);
8+
reject(new TimeoutError(`Timed out in + ${ms} + ms.`));
9+
}, ms);
10+
});
11+
12+
// Returns a race between our timeout and the passed in promise
13+
return Promise.race([promise, timeout]);
14+
}

0 commit comments

Comments
 (0)