@blakearoberts/visage 0.0.1-rc.4 → 0.0.1-rc.5
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 +6 -4
- package/dist/certs.d.ts +1 -2
- package/dist/certs.d.ts.map +1 -1
- package/dist/config.d.ts +29 -33
- package/dist/config.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +115 -63
- package/dist/types.d.ts +20 -27
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -97,15 +97,17 @@ flowchart LR
|
|
|
97
97
|
|
|
98
98
|
### mkcert
|
|
99
99
|
|
|
100
|
-
Visage downloads [`mkcert`](https://github.com/FiloSottile/mkcert) from `dl.filippo.io` when the Vite dev server starts. Visage uses it to install a local certificate authority and generate HTTPS certificates for the local proxy.
|
|
100
|
+
Visage downloads [`mkcert`](https://github.com/FiloSottile/mkcert) from `dl.filippo.io` into `$XDG_CACHE_HOME/visage/bin/mkcert-<platform>-<arch>` when the Vite dev server starts. Visage uses it to install a local certificate authority and generate HTTPS certificates for the local proxy.
|
|
101
101
|
|
|
102
102
|
### Docker Images
|
|
103
103
|
|
|
104
104
|
Visage pulls these as needed based on configuration:
|
|
105
105
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
| Service | Image | Source |
|
|
107
|
+
| ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------- | ------------------------- |
|
|
108
|
+
| [NGINX](https://nginx.org/) | [`nginx:1.30.0-alpine`](https://hub.docker.com/_/nginx) | Docker Hub |
|
|
109
|
+
| [OAuth2 Proxy](https://oauth2-proxy.github.io/oauth2-proxy/) | [`quay.io/oauth2-proxy/oauth2-proxy:v7.15.2`](https://quay.io/repository/oauth2-proxy/oauth2-proxy) | Quay |
|
|
110
|
+
| [Dex](https://dexidp.io/) | [`ghcr.io/dexidp/dex:v2.45.1`](https://github.com/dexidp/dex/pkgs/container/dex) | GitHub Container Registry |
|
|
109
111
|
|
|
110
112
|
## Security Notes
|
|
111
113
|
|
package/dist/certs.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
type Options = {
|
|
2
|
-
bin: string;
|
|
3
2
|
certs: string;
|
|
4
3
|
hostname: string;
|
|
5
4
|
};
|
|
6
|
-
export declare function ensureCerts({
|
|
5
|
+
export declare function ensureCerts({ certs, hostname }: Options): Promise<void>;
|
|
7
6
|
export {};
|
|
8
7
|
//# sourceMappingURL=certs.d.ts.map
|
package/dist/certs.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"certs.d.ts","sourceRoot":"","sources":["../src/certs.ts"],"names":[],"mappings":"AAOA,KAAK,OAAO,GAAG;IACb,
|
|
1
|
+
{"version":3,"file":"certs.d.ts","sourceRoot":"","sources":["../src/certs.ts"],"names":[],"mappings":"AAOA,KAAK,OAAO,GAAG;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAsB,WAAW,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAuC7E"}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ResolvedConfig } from 'vite';
|
|
2
|
-
import type { VisageDexExpiry, VisageDexUser, VisageOptions, VisageService, VisageUpstream } from './types';
|
|
2
|
+
import type { VisageDexExpiry, VisageDexOptions, VisageDexUser, VisageExternalIdpOptions, VisageOptions, VisageService, VisageUpstream } from './types';
|
|
3
3
|
type Volume = readonly [from: string, to: string];
|
|
4
4
|
type ResolvedCookiePolicy = {
|
|
5
5
|
readonly cookie_name: string;
|
|
@@ -8,43 +8,21 @@ type ResolvedCookiePolicy = {
|
|
|
8
8
|
readonly cookie_domains?: readonly string[];
|
|
9
9
|
readonly cookie_path: string;
|
|
10
10
|
};
|
|
11
|
-
type ResolvedDexConfig = {
|
|
12
|
-
readonly expiry?: VisageDexExpiry;
|
|
13
|
-
readonly users: readonly Required<VisageDexUser>[];
|
|
14
|
-
};
|
|
15
11
|
type ResolvedIdpOption = {
|
|
16
|
-
readonly path: string;
|
|
17
|
-
readonly upstream: string;
|
|
18
|
-
readonly issuer?: string;
|
|
19
|
-
readonly authorizationEndpoint?: string;
|
|
20
|
-
readonly tokenEndpoint?: string;
|
|
21
|
-
readonly jwksEndpoint?: string;
|
|
22
|
-
} & ({
|
|
23
|
-
readonly kind: 'dex';
|
|
24
|
-
readonly dex: ResolvedDexConfig;
|
|
25
|
-
} | {
|
|
26
|
-
readonly kind: 'external';
|
|
27
|
-
});
|
|
28
|
-
type ResolvedIdp = {
|
|
29
|
-
readonly issuer: string;
|
|
30
|
-
readonly authorizationEndpoint: string;
|
|
31
|
-
readonly tokenEndpoint: string;
|
|
32
|
-
readonly jwksEndpoint: string;
|
|
33
|
-
readonly upstream: string;
|
|
34
|
-
} & ({
|
|
35
12
|
readonly kind: 'dex';
|
|
36
|
-
readonly dex:
|
|
37
|
-
} |
|
|
38
|
-
readonly kind: 'external';
|
|
39
|
-
});
|
|
13
|
+
readonly dex: VisageDexOptions;
|
|
14
|
+
} | VisageExternalIdpOptions;
|
|
40
15
|
type ResolvedOAuth2Client = {
|
|
41
16
|
readonly id: string;
|
|
42
17
|
readonly secret?: string;
|
|
43
18
|
readonly scopes: readonly string[];
|
|
44
19
|
readonly public: boolean;
|
|
45
20
|
};
|
|
21
|
+
type ResolvedService = VisageService & {
|
|
22
|
+
readonly image: string;
|
|
23
|
+
};
|
|
46
24
|
type ResolvedUpstream = VisageUpstream & {
|
|
47
|
-
readonly scheme:
|
|
25
|
+
readonly scheme: 'http' | 'https';
|
|
48
26
|
};
|
|
49
27
|
type ResolvedVisageOptions = {
|
|
50
28
|
readonly host: string;
|
|
@@ -52,14 +30,32 @@ type ResolvedVisageOptions = {
|
|
|
52
30
|
readonly cookie: ResolvedCookiePolicy;
|
|
53
31
|
readonly idp: ResolvedIdpOption;
|
|
54
32
|
readonly oauth2: ResolvedOAuth2Client;
|
|
55
|
-
readonly services
|
|
33
|
+
readonly services: Readonly<Record<string, ResolvedService>>;
|
|
56
34
|
readonly upstreams?: Record<string, ResolvedUpstream>;
|
|
57
35
|
};
|
|
36
|
+
type ResolvedBaseIdpConfig = {
|
|
37
|
+
readonly upstream: string;
|
|
38
|
+
readonly issuer: string;
|
|
39
|
+
readonly authorization: string;
|
|
40
|
+
readonly token: string;
|
|
41
|
+
readonly jwks: string;
|
|
42
|
+
};
|
|
43
|
+
type ResolvedDexIdpConfig = ResolvedBaseIdpConfig & {
|
|
44
|
+
readonly kind: 'dex';
|
|
45
|
+
readonly dex: {
|
|
46
|
+
readonly expiry?: VisageDexExpiry;
|
|
47
|
+
readonly users: readonly VisageDexUser[];
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
type ResolvedExternalIdpConfig = ResolvedBaseIdpConfig & {
|
|
51
|
+
readonly kind: 'external';
|
|
52
|
+
};
|
|
53
|
+
type ResolvedIdpConfig = ResolvedDexIdpConfig | ResolvedExternalIdpConfig;
|
|
58
54
|
export type VisageConfig = {
|
|
59
55
|
readonly host: string;
|
|
60
56
|
readonly port: number;
|
|
61
57
|
readonly cookie: ResolvedCookiePolicy;
|
|
62
|
-
readonly idp:
|
|
58
|
+
readonly idp: ResolvedIdpConfig;
|
|
63
59
|
readonly oauth2: ResolvedOAuth2Client;
|
|
64
60
|
readonly cache: string;
|
|
65
61
|
readonly files: {
|
|
@@ -70,10 +66,10 @@ export type VisageConfig = {
|
|
|
70
66
|
readonly oauth2Proxy: Volume;
|
|
71
67
|
readonly oauth2ProxyClientSecret: Volume;
|
|
72
68
|
};
|
|
73
|
-
readonly services: Readonly<Record<string,
|
|
69
|
+
readonly services: Readonly<Record<string, ResolvedService>>;
|
|
74
70
|
readonly upstreams: Readonly<Record<string, ResolvedUpstream>>;
|
|
75
71
|
};
|
|
76
|
-
export declare function resolveOptions(
|
|
72
|
+
export declare function resolveOptions(options: VisageOptions): ResolvedVisageOptions;
|
|
77
73
|
export declare function resolveConfig(options: ResolvedVisageOptions, config: ResolvedConfig, vitePort: number): VisageConfig;
|
|
78
74
|
export {};
|
|
79
75
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAE3C,OAAO,KAAK,EACV,eAAe,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Plugin } from 'vite';
|
|
2
2
|
import type { VisageOptions } from './types';
|
|
3
|
-
export type { VisageCookiePolicy, VisageDexExpiry, VisageDexOptions, VisageDexUser,
|
|
3
|
+
export type { VisageCookiePolicy, VisageDexExpiry, VisageDexOptions, VisageDexUser, VisageExternalIdpOptions, VisageOAuth2Client, VisageOptions, VisageProxyPolicy, VisageService, VisageUpstream, } from './types';
|
|
4
4
|
export declare function visage(options?: VisageOptions): Plugin;
|
|
5
5
|
export default visage;
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAOnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,YAAY,EACV,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAOnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,YAAY,EACV,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,wBAAwB,EACxB,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,aAAa,EACb,cAAc,GACf,MAAM,SAAS,CAAC;AAEjB,wBAAgB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,MAAM,CAkD1D;AAED,eAAe,MAAM,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { dirname, join } from 'node:path';
|
|
2
2
|
import { spawnSync } from 'node:child_process';
|
|
3
|
-
import { existsSync, mkdirSync,
|
|
3
|
+
import { existsSync, mkdirSync, chmodSync, createWriteStream, readFileSync, appendFileSync, writeFileSync } from 'node:fs';
|
|
4
4
|
import { homedir } from 'node:os';
|
|
5
5
|
import { Readable } from 'node:stream';
|
|
6
6
|
import { pipeline } from 'node:stream/promises';
|
|
@@ -56,18 +56,19 @@ function onSigTerm() {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
async function ensureCerts({
|
|
59
|
+
async function ensureCerts({ certs, hostname }) {
|
|
60
60
|
const cert = join(certs, 'tls.crt');
|
|
61
61
|
const key = join(certs, 'tls.key');
|
|
62
62
|
if (existsSync(cert) && existsSync(key))
|
|
63
63
|
return;
|
|
64
|
-
const mkcert = await ensureMkCert(
|
|
64
|
+
const mkcert = await ensureMkCert();
|
|
65
65
|
const env = {
|
|
66
66
|
...process.env,
|
|
67
67
|
CAROOT: join(process.env.XDG_CACHE_HOME || join(homedir(), '.cache'), 'visage/ca'),
|
|
68
68
|
TRUST_STORES: process.env.TRUST_STORES ?? 'system',
|
|
69
69
|
};
|
|
70
|
-
mkdirSync(env.CAROOT, { recursive: true });
|
|
70
|
+
mkdirSync(env.CAROOT, { recursive: true, mode: 0o700 });
|
|
71
|
+
chmodSync(env.CAROOT, 0o700);
|
|
71
72
|
// mkcert -install is idempotent; CA files alone do not prove trust-store state.
|
|
72
73
|
{
|
|
73
74
|
const result = spawnSync(mkcert, ['-install'], {
|
|
@@ -91,8 +92,9 @@ async function ensureCerts({ bin, certs, hostname, }) {
|
|
|
91
92
|
throw new Error('Failed to generate TLS certificates');
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
|
-
async function ensureMkCert(
|
|
95
|
-
const
|
|
95
|
+
async function ensureMkCert() {
|
|
96
|
+
const bin = join(process.env.XDG_CACHE_HOME || join(homedir(), '.cache'), 'visage/bin');
|
|
97
|
+
const file = join(bin, `mkcert-${process.platform}-${process.arch}`);
|
|
96
98
|
if (existsSync(file))
|
|
97
99
|
return file;
|
|
98
100
|
mkdirSync(bin, { recursive: true });
|
|
@@ -314,9 +316,9 @@ function renderOauth2ProxyConfig(config) {
|
|
|
314
316
|
provider: 'oidc',
|
|
315
317
|
oidc_issuer_url: config.idp.issuer,
|
|
316
318
|
skip_oidc_discovery: true,
|
|
317
|
-
login_url: config.idp.
|
|
318
|
-
redeem_url: config.idp.
|
|
319
|
-
oidc_jwks_url: config.idp.
|
|
319
|
+
login_url: config.idp.authorization,
|
|
320
|
+
redeem_url: config.idp.token,
|
|
321
|
+
oidc_jwks_url: config.idp.jwks,
|
|
320
322
|
redirect_url: `https://${config.host}:${config.port}/oauth2/callback`,
|
|
321
323
|
client_id: config.oauth2.id,
|
|
322
324
|
...(config.oauth2.secret === undefined
|
|
@@ -376,22 +378,23 @@ const BaseFiles = {
|
|
|
376
378
|
],
|
|
377
379
|
oauth2Proxy: ['./oauth2-proxy.yml', '/etc/oauth2-proxy/config.yml'],
|
|
378
380
|
};
|
|
381
|
+
const BaseDexService = {
|
|
382
|
+
image: 'ghcr.io/dexidp/dex:v2.45.1',
|
|
383
|
+
command: ['dex', 'serve', '/etc/dex/dex.yml'],
|
|
384
|
+
};
|
|
385
|
+
const BaseServiceNginx = {
|
|
386
|
+
image: 'nginx:1.30.0-alpine',
|
|
387
|
+
depends_on: ['oauth2_proxy'],
|
|
388
|
+
extra_hosts: ['host.docker.internal:host-gateway'],
|
|
389
|
+
};
|
|
390
|
+
const BaseOAuth2ProxyService = {
|
|
391
|
+
image: 'quay.io/oauth2-proxy/oauth2-proxy:v7.15.2',
|
|
392
|
+
command: ['--config', '/etc/oauth2-proxy/config.yml'],
|
|
393
|
+
extra_hosts: ['host.docker.internal:host-gateway'],
|
|
394
|
+
};
|
|
379
395
|
const BaseServices = {
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
command: ['dex', 'serve', '/etc/dex/dex.yml'],
|
|
383
|
-
},
|
|
384
|
-
nginx: {
|
|
385
|
-
image: 'nginx:1.30.0-alpine',
|
|
386
|
-
depends_on: ['oauth2_proxy', 'dex'],
|
|
387
|
-
extra_hosts: ['host.docker.internal:host-gateway'],
|
|
388
|
-
},
|
|
389
|
-
oauth2_proxy: {
|
|
390
|
-
image: 'quay.io/oauth2-proxy/oauth2-proxy:v7.15.2',
|
|
391
|
-
command: ['--config', '/etc/oauth2-proxy/config.yml'],
|
|
392
|
-
depends_on: ['dex'],
|
|
393
|
-
extra_hosts: ['host.docker.internal:host-gateway'],
|
|
394
|
-
},
|
|
396
|
+
nginx: BaseServiceNginx,
|
|
397
|
+
oauth2_proxy: BaseOAuth2ProxyService,
|
|
395
398
|
};
|
|
396
399
|
const BaseDexUpstream = {
|
|
397
400
|
host: 'dex',
|
|
@@ -441,11 +444,6 @@ const DefaultDexUsers = [
|
|
|
441
444
|
password: 'pass',
|
|
442
445
|
},
|
|
443
446
|
];
|
|
444
|
-
const DefaultIdpConfig = {
|
|
445
|
-
kind: 'dex',
|
|
446
|
-
path: '/dex',
|
|
447
|
-
upstream: 'dex',
|
|
448
|
-
};
|
|
449
447
|
const DefaultOAuth2Client = {
|
|
450
448
|
id: 'visage',
|
|
451
449
|
secret: 'visage-secret',
|
|
@@ -460,7 +458,8 @@ const DefaultProxyPolicy = {
|
|
|
460
458
|
'X-Forwarded-Proto': '$scheme',
|
|
461
459
|
},
|
|
462
460
|
};
|
|
463
|
-
function resolveOptions(
|
|
461
|
+
function resolveOptions(options) {
|
|
462
|
+
const { host = 'local.vite.app', port = 9001, cookie = {}, oauth2 = {}, } = options;
|
|
464
463
|
const cookieName = cookie.name ?? 'session';
|
|
465
464
|
const publicClient = oauth2.clientSecret === null;
|
|
466
465
|
return {
|
|
@@ -482,7 +481,7 @@ function resolveOptions({ host = 'local.vite.app', port = 9001, cookie = {}, idp
|
|
|
482
481
|
: { cookie_domains: cookie.domains }),
|
|
483
482
|
...(cookie.path === undefined ? {} : { cookie_path: cookie.path }),
|
|
484
483
|
},
|
|
485
|
-
idp: resolveIdpOption(idp),
|
|
484
|
+
idp: resolveIdpOption(options.idp),
|
|
486
485
|
oauth2: {
|
|
487
486
|
id: oauth2.clientId ?? DefaultOAuth2Client.id,
|
|
488
487
|
...(publicClient
|
|
@@ -491,11 +490,33 @@ function resolveOptions({ host = 'local.vite.app', port = 9001, cookie = {}, idp
|
|
|
491
490
|
scopes: oauth2.scopes ?? DefaultOAuth2Client.scopes,
|
|
492
491
|
public: publicClient,
|
|
493
492
|
},
|
|
494
|
-
|
|
495
|
-
|
|
493
|
+
services: {
|
|
494
|
+
...options.services,
|
|
495
|
+
nginx: {
|
|
496
|
+
...BaseServiceNginx,
|
|
497
|
+
...{
|
|
498
|
+
...options.services?.nginx,
|
|
499
|
+
extra_hosts: [
|
|
500
|
+
...BaseServiceNginx.extra_hosts,
|
|
501
|
+
...(options.services?.nginx?.extra_hosts ?? []),
|
|
502
|
+
],
|
|
503
|
+
},
|
|
504
|
+
},
|
|
505
|
+
oauth2_proxy: {
|
|
506
|
+
...BaseOAuth2ProxyService,
|
|
507
|
+
...{
|
|
508
|
+
...options.services?.oauth2_proxy,
|
|
509
|
+
extra_hosts: [
|
|
510
|
+
...BaseOAuth2ProxyService.extra_hosts,
|
|
511
|
+
...(options.services?.oauth2_proxy?.extra_hosts ?? []),
|
|
512
|
+
],
|
|
513
|
+
},
|
|
514
|
+
},
|
|
515
|
+
},
|
|
516
|
+
...(options.upstreams === undefined
|
|
496
517
|
? {}
|
|
497
518
|
: {
|
|
498
|
-
upstreams: Object.fromEntries(Object.entries(upstreams).map(([name, upstream]) => [
|
|
519
|
+
upstreams: Object.fromEntries(Object.entries(options.upstreams).map(([name, upstream]) => [
|
|
499
520
|
name,
|
|
500
521
|
{ ...upstream, scheme: upstream.scheme ?? 'http' },
|
|
501
522
|
])),
|
|
@@ -503,18 +524,17 @@ function resolveOptions({ host = 'local.vite.app', port = 9001, cookie = {}, idp
|
|
|
503
524
|
};
|
|
504
525
|
}
|
|
505
526
|
function resolveIdpOption(idp) {
|
|
506
|
-
function normalizePath(path) {
|
|
507
|
-
const pathWithLeadingSlash = path.startsWith('/') ? path : `/${path}`;
|
|
508
|
-
return pathWithLeadingSlash.endsWith('/')
|
|
509
|
-
? pathWithLeadingSlash.slice(0, -1)
|
|
510
|
-
: pathWithLeadingSlash;
|
|
511
|
-
}
|
|
512
527
|
if (idp?.kind === 'external') {
|
|
513
|
-
|
|
514
|
-
|
|
528
|
+
return {
|
|
529
|
+
kind: 'external',
|
|
530
|
+
issuer: idp.issuer,
|
|
531
|
+
authorization: idp.authorization ?? '/auth',
|
|
532
|
+
token: idp.token ?? '/token',
|
|
533
|
+
jwks: idp.jwks ?? '/keys',
|
|
534
|
+
};
|
|
515
535
|
}
|
|
516
536
|
return {
|
|
517
|
-
|
|
537
|
+
kind: 'dex',
|
|
518
538
|
dex: {
|
|
519
539
|
...(idp?.expiry ? { expiry: idp.expiry } : {}),
|
|
520
540
|
users: (idp?.users ?? DefaultDexUsers).map((user) => ({
|
|
@@ -526,47 +546,80 @@ function resolveIdpOption(idp) {
|
|
|
526
546
|
},
|
|
527
547
|
};
|
|
528
548
|
}
|
|
549
|
+
function resolveIdpConfig({ host, port, idp, }) {
|
|
550
|
+
if (idp.kind === 'dex') {
|
|
551
|
+
const issuer = `https://${host}:${port}/dex`;
|
|
552
|
+
const upstream = `http://dex:5556/dex`;
|
|
553
|
+
return {
|
|
554
|
+
kind: 'dex',
|
|
555
|
+
upstream: 'dex',
|
|
556
|
+
issuer,
|
|
557
|
+
authorization: `${issuer}/auth`,
|
|
558
|
+
token: `${upstream}/token`,
|
|
559
|
+
jwks: `${upstream}/keys`,
|
|
560
|
+
dex: {
|
|
561
|
+
expiry: idp.dex.expiry,
|
|
562
|
+
users: (idp.dex?.users ?? DefaultDexUsers).map((user) => ({
|
|
563
|
+
email: user.email,
|
|
564
|
+
password: user.password,
|
|
565
|
+
username: user.username ?? user.email.split('@', 1)[0],
|
|
566
|
+
userID: user.userID ?? user.email,
|
|
567
|
+
})),
|
|
568
|
+
},
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
return {
|
|
572
|
+
kind: 'external',
|
|
573
|
+
upstream: 'idp',
|
|
574
|
+
issuer: idp.issuer,
|
|
575
|
+
authorization: idp.issuer + (idp.authorization ?? '/auth'),
|
|
576
|
+
token: idp.issuer + (idp.token ?? '/token'),
|
|
577
|
+
jwks: idp.issuer + (idp.jwks ?? '/keys'),
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
function resolveExternalIdpUpstream(idp) {
|
|
581
|
+
const issuer = new URL(idp.issuer);
|
|
582
|
+
return {
|
|
583
|
+
host: issuer.hostname,
|
|
584
|
+
scheme: issuer.protocol === 'https:' ? 'https' : 'http',
|
|
585
|
+
port: Number(issuer.port) || (issuer.protocol === 'https:' ? 443 : 80),
|
|
586
|
+
locations: { [issuer.pathname]: { auth: { enabled: false } } },
|
|
587
|
+
};
|
|
588
|
+
}
|
|
529
589
|
function resolveConfig(options, config, vitePort) {
|
|
590
|
+
const idp = resolveIdpConfig(options);
|
|
530
591
|
const upstreams = {
|
|
531
592
|
oauth2_proxy: BaseOauth2ProxyUpstream,
|
|
532
593
|
vite: { ...BaseViteUpstream, port: vitePort },
|
|
533
|
-
...(
|
|
594
|
+
...(idp.kind === 'dex'
|
|
595
|
+
? { dex: BaseDexUpstream }
|
|
596
|
+
: { idp: resolveExternalIdpUpstream(idp) }),
|
|
534
597
|
...options.upstreams,
|
|
535
598
|
};
|
|
536
|
-
const { host: idpHost, port: idpPort, scheme: idpScheme, } = upstreams[options.idp.upstream];
|
|
537
|
-
const origin = `https://${options.host}:${options.port}`;
|
|
538
|
-
const idpOrigin = `${idpScheme}://${idpHost}:${idpPort}`;
|
|
539
|
-
const idpBase = {
|
|
540
|
-
upstream: options.idp.upstream,
|
|
541
|
-
issuer: options.idp.issuer ?? `${origin}${options.idp.path}`,
|
|
542
|
-
authorizationEndpoint: options.idp.authorizationEndpoint ?? `${origin}${options.idp.path}/auth`,
|
|
543
|
-
tokenEndpoint: options.idp.tokenEndpoint ?? `${idpOrigin}${options.idp.path}/token`,
|
|
544
|
-
jwksEndpoint: options.idp.jwksEndpoint ?? `${idpOrigin}${options.idp.path}/keys`,
|
|
545
|
-
};
|
|
546
599
|
return {
|
|
547
600
|
host: options.host,
|
|
548
601
|
port: options.port,
|
|
549
602
|
cookie: options.cookie,
|
|
550
|
-
idp
|
|
551
|
-
? { ...idpBase, kind: 'dex', dex: options.idp.dex }
|
|
552
|
-
: { ...idpBase, kind: 'external' },
|
|
603
|
+
idp,
|
|
553
604
|
oauth2: options.oauth2,
|
|
554
605
|
cache: join(config.cacheDir, 'visage'),
|
|
555
606
|
files: { ...BaseFiles },
|
|
556
607
|
services: {
|
|
557
|
-
...(
|
|
558
|
-
?
|
|
559
|
-
|
|
608
|
+
...(idp.kind === 'dex'
|
|
609
|
+
? {
|
|
610
|
+
dex: BaseDexService,
|
|
560
611
|
nginx: {
|
|
561
612
|
...BaseServices.nginx,
|
|
562
|
-
depends_on: ['oauth2_proxy'],
|
|
613
|
+
depends_on: ['dex', 'oauth2_proxy'],
|
|
563
614
|
},
|
|
564
615
|
oauth2_proxy: {
|
|
565
616
|
command: BaseServices.oauth2_proxy.command,
|
|
566
617
|
extra_hosts: BaseServices.oauth2_proxy.extra_hosts,
|
|
567
618
|
image: BaseServices.oauth2_proxy.image,
|
|
619
|
+
depends_on: ['dex'],
|
|
568
620
|
},
|
|
569
|
-
}
|
|
621
|
+
}
|
|
622
|
+
: BaseServices),
|
|
570
623
|
...options.services,
|
|
571
624
|
},
|
|
572
625
|
upstreams: Object.fromEntries(Object.entries(upstreams).map(([name, upstream]) => [
|
|
@@ -607,7 +660,6 @@ function visage(options = {}) {
|
|
|
607
660
|
async function startVisage(port) {
|
|
608
661
|
const config = resolveConfig(resolvedOptions, server.config, port);
|
|
609
662
|
await ensureCerts({
|
|
610
|
-
bin: join(config.cache, 'bin'),
|
|
611
663
|
certs: join(config.cache, config.files.certs[0]),
|
|
612
664
|
hostname: config.host,
|
|
613
665
|
});
|
package/dist/types.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export type VisageOptions = {
|
|
|
22
22
|
* Identity provider configuration. Omit this to use Visage's managed Dex
|
|
23
23
|
* provider.
|
|
24
24
|
*/
|
|
25
|
-
readonly idp?: VisageDexOptions |
|
|
25
|
+
readonly idp?: VisageDexOptions | VisageExternalIdpOptions;
|
|
26
26
|
/**
|
|
27
27
|
* OAuth2 client settings shared by Dex or an external IdP and OAuth2 Proxy.
|
|
28
28
|
*/
|
|
@@ -164,45 +164,36 @@ export type VisageDexUser = {
|
|
|
164
164
|
/**
|
|
165
165
|
* External OpenID Connect identity provider options.
|
|
166
166
|
*/
|
|
167
|
-
export type
|
|
167
|
+
export type VisageExternalIdpOptions = {
|
|
168
168
|
/**
|
|
169
169
|
* Selects the external IdP flow.
|
|
170
170
|
*/
|
|
171
171
|
readonly kind: 'external';
|
|
172
172
|
/**
|
|
173
|
-
*
|
|
173
|
+
* OIDC issuer URL used by OAuth2 Proxy.
|
|
174
174
|
*/
|
|
175
|
-
readonly
|
|
175
|
+
readonly issuer: string;
|
|
176
176
|
/**
|
|
177
|
-
*
|
|
177
|
+
* OIDC authorization path appended to
|
|
178
|
+
* {@link VisageExternalIdpOptions.issuer}.
|
|
178
179
|
*
|
|
179
|
-
* @defaultValue
|
|
180
|
+
* @defaultValue '/auth'
|
|
180
181
|
*/
|
|
181
|
-
readonly
|
|
182
|
-
/**
|
|
183
|
-
* OIDC issuer URL. Defaults to the Visage origin plus
|
|
184
|
-
* {@link VisageIdpOptions.path}.
|
|
185
|
-
*/
|
|
186
|
-
readonly issuer?: string;
|
|
187
|
-
/**
|
|
188
|
-
* Browser-facing authorization endpoint URL. Defaults to the Visage origin
|
|
189
|
-
* plus {@link VisageIdpOptions.path} and `/auth`.
|
|
190
|
-
*/
|
|
191
|
-
readonly authorizationEndpoint?: string;
|
|
182
|
+
readonly authorization?: string;
|
|
192
183
|
/**
|
|
193
|
-
*
|
|
184
|
+
* OIDC token endpoint path appended to
|
|
185
|
+
* {@link VisageExternalIdpOptions.issuer}.
|
|
194
186
|
*
|
|
195
|
-
*
|
|
196
|
-
* {@link VisageIdpOptions.path} and `/token`.
|
|
187
|
+
* @defaultValue '/token'
|
|
197
188
|
*/
|
|
198
|
-
readonly
|
|
189
|
+
readonly token?: string;
|
|
199
190
|
/**
|
|
200
|
-
* JWKS endpoint
|
|
191
|
+
* OIDC JWKS endpoint path appended to
|
|
192
|
+
* {@link VisageExternalIdpOptions.issuer}.
|
|
201
193
|
*
|
|
202
|
-
*
|
|
203
|
-
* {@link VisageIdpOptions.path} and `/keys`.
|
|
194
|
+
* @defaultValue '/keys'
|
|
204
195
|
*/
|
|
205
|
-
readonly
|
|
196
|
+
readonly jwks?: string;
|
|
206
197
|
};
|
|
207
198
|
/**
|
|
208
199
|
* OAuth2 client configuration used by OAuth2 Proxy and, for managed Dex, the
|
|
@@ -236,9 +227,11 @@ export type VisageOAuth2Client = {
|
|
|
236
227
|
*/
|
|
237
228
|
export type VisageService = {
|
|
238
229
|
/**
|
|
239
|
-
* Container image reference used for the service.
|
|
230
|
+
* Container image reference used for the service. Required for additional
|
|
231
|
+
* services; defaults to the managed image when overriding `nginx` or
|
|
232
|
+
* `oauth2_proxy`.
|
|
240
233
|
*/
|
|
241
|
-
readonly image
|
|
234
|
+
readonly image?: string;
|
|
242
235
|
/**
|
|
243
236
|
* Optional command override rendered into the Compose service.
|
|
244
237
|
*/
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,kBAAkB,CAAC;IACrC;;;OAGG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,gBAAgB,GAAG,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED