@blakearoberts/visage 0.0.1-rc.6 → 0.0.1-rc.8

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 CHANGED
@@ -125,7 +125,7 @@ Do not treat the managed Dex and OAuth2 Proxy defaults as production auth infras
125
125
  - If startup fails immediately, confirm Docker is running and `docker compose` works.
126
126
  - If NGINX cannot start, check whether the configured `port` is already in use.
127
127
  - If the hostname cannot be resolved, Visage may need permission to update `/etc/hosts`.
128
- - If the browser rejects the certificate, allow the local certificate authority prompt from `mkcert`.
128
+ - If the browser rejects the certificate, allow the local certificate authority prompt from `mkcert`; CI test runners should be configured to ignore local HTTPS errors.
129
129
 
130
130
  ## TO-DO
131
131
 
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"certs.d.ts","sourceRoot":"","sources":["../src/certs.ts"],"names":[],"mappings":"AAcA,KAAK,OAAO,GAAG;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAIF,wBAAsB,WAAW,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA0C7E"}
@@ -1 +1 @@
1
- {"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAGA,KAAK,WAAW,GAAG,MAAM,IAAI,CAAC;AAI9B,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAoBtD"}
1
+ {"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAIA,KAAK,WAAW,GAAG,MAAM,IAAI,CAAC;AAI9B,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAwCtD"}
package/dist/config.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { ResolvedConfig } from 'vite';
2
- import type { VisageDexExpiry, VisageDexOptions, VisageDexUser, VisageExternalIdpOptions, VisageOptions, VisageService, VisageUpstream } from './types';
2
+ import type { VisageDexExpiry, VisageDexOptions, VisageDexUser, VisageExternalIdpOptions, VisageOptions, VisageProxyPolicy, VisageService, VisageUpstream } from './types';
3
3
  type Volume = readonly [from: string, to: string];
4
4
  type ResolvedCookiePolicy = {
5
5
  readonly cookie_name: string;
@@ -17,20 +17,14 @@ type ResolvedOAuth2Client = {
17
17
  readonly scopes: readonly string[];
18
18
  readonly public: boolean;
19
19
  };
20
- type ResolvedService = Omit<VisageService, 'upstream'>;
21
- type ResolvedUpstream = Omit<VisageUpstream, 'host' | 'port' | 'scheme'> & {
22
- readonly host: string;
23
- readonly port: number;
24
- readonly scheme: 'http' | 'https';
25
- };
26
20
  type ResolvedVisageOptions = {
27
21
  readonly host: string;
28
22
  readonly port: number;
29
23
  readonly cookie: ResolvedCookiePolicy;
30
24
  readonly idp: ResolvedIdpOption;
31
25
  readonly oauth2: ResolvedOAuth2Client;
32
- readonly services: Readonly<Record<string, ResolvedService>>;
33
- readonly upstreams?: Record<string, ResolvedUpstream>;
26
+ readonly services: Readonly<Record<string, VisageService>>;
27
+ readonly upstreams: Record<string, VisageUpstream>;
34
28
  };
35
29
  type ResolvedBaseIdpConfig = {
36
30
  readonly upstream: string;
@@ -49,6 +43,20 @@ type ResolvedExternalIdpConfig = ResolvedBaseIdpConfig & {
49
43
  readonly dex?: never;
50
44
  };
51
45
  type ResolvedIdpConfig = ResolvedDexIdpConfig | ResolvedExternalIdpConfig;
46
+ type ResolvedService = Omit<VisageService, 'upstream'>;
47
+ type ResolvedUpstream = {
48
+ readonly scheme: 'http' | 'https';
49
+ readonly host: string;
50
+ readonly port: number;
51
+ readonly locations: Readonly<Record<string, VisageProxyPolicy>>;
52
+ };
53
+ type ResolvedProxyPolicy = {
54
+ readonly auth: Required<VisageProxyPolicy['auth']>;
55
+ readonly headers: VisageProxyPolicy['headers'];
56
+ };
57
+ type ResolvedConfigUpstream = Omit<ResolvedUpstream, 'locations'> & {
58
+ readonly locations: Readonly<Record<string, ResolvedProxyPolicy>>;
59
+ };
52
60
  export type VisageConfig = {
53
61
  readonly host: string;
54
62
  readonly port: number;
@@ -65,7 +73,7 @@ export type VisageConfig = {
65
73
  readonly oauth2ProxyClientSecret: Volume;
66
74
  };
67
75
  readonly services: Readonly<Record<string, ResolvedService>>;
68
- readonly upstreams: Readonly<Record<string, ResolvedUpstream>>;
76
+ readonly upstreams: Readonly<Record<string, ResolvedConfigUpstream>>;
69
77
  };
70
78
  export declare function resolveOptions(options: VisageOptions): ResolvedVisageOptions;
71
79
  export declare function resolveConfig(options: ResolvedVisageOptions, config: ResolvedConfig, vitePort: number): VisageConfig;
@@ -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,EACf,gBAAgB,EAChB,aAAa,EACb,wBAAwB,EACxB,aAAa,EAEb,aAAa,EACb,cAAc,EACf,MAAM,SAAS,CAAC;AAEjB,KAAK,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;AAElD,KAAK,oBAAoB,GAAG;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,KAAK,iBAAiB,GAClB;IACE,QAAQ,CAAC,GAAG,EAAE,gBAAgB,CAAC;CAChC,GACD,wBAAwB,CAAC;AAE7B,KAAK,oBAAoB,GAAG;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,KAAK,eAAe,GAAG,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;AAEvD,KAAK,gBAAgB,GAAG,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC,GAAG;IACzE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;CACnC,CAAC;AAEF,KAAK,qBAAqB,GAAG;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,GAAG,EAAE,iBAAiB,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;IAC7D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CACvD,CAAC;AAEF,KAAK,qBAAqB,GAAG;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AACF,KAAK,oBAAoB,GAAG,qBAAqB,GAAG;IAClD,QAAQ,CAAC,GAAG,EAAE;QACZ,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC;QAClC,QAAQ,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;KAC1C,CAAC;CACH,CAAC;AACF,KAAK,yBAAyB,GAAG,qBAAqB,GAAG;IACvD,QAAQ,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC;CACtB,CAAC;AACF,KAAK,iBAAiB,GAAG,oBAAoB,GAAG,yBAAyB,CAAC;AAE1E,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,GAAG,EAAE,iBAAiB,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IAEtC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE;QACd,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;QAC7B,QAAQ,CAAC,uBAAuB,EAAE,MAAM,CAAC;KAC1C,CAAC;IAEF,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;IAC7D,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;CAChE,CAAC;AA2GF,wBAAgB,cAAc,CAAC,OAAO,EAAE,aAAa,GAAG,qBAAqB,CAmE5E;AAqHD,wBAAgB,aAAa,CAC3B,OAAO,EAAE,qBAAqB,EAC9B,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,GACf,YAAY,CAsDd"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -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,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"}
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;AAG7C,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;AAUjB,wBAAgB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,MAAM,CAgE1D;AAED,eAAe,MAAM,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { dirname, join } from 'node:path';
2
- import { spawnSync } from 'node:child_process';
3
- import { existsSync, mkdirSync, chmodSync, createWriteStream, readFileSync, appendFileSync, writeFileSync } from 'node:fs';
1
+ import { join, dirname } from 'node:path';
2
+ import { spawn, spawnSync } from 'node:child_process';
3
+ import { mkdirSync, openSync, chmodSync, rmSync, existsSync, 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';
@@ -9,83 +9,78 @@ import { hashSync } from 'bcryptjs';
9
9
  import { Eta } from 'eta';
10
10
  import { createHash } from 'node:crypto';
11
11
 
12
- let stopCompose;
12
+ let stopRef;
13
13
  function startCompose(file) {
14
- stopCompose?.();
15
- stopCompose = undefined;
14
+ stopRef?.();
15
+ stopRef = undefined;
16
+ const logs = join(dirname(file), 'logs');
17
+ mkdirSync(logs, { recursive: true });
18
+ const output = openSync(join(logs, 'compose.log'), 'w');
19
+ const compose = [
20
+ 'compose',
21
+ `--project-name=${process.env.COMPOSE_PROJECT_NAME ?? 'visage'}`,
22
+ `--file=${file}`,
23
+ ];
24
+ const env = { ...process.env, COMPOSE_MENU: 'false' };
25
+ const opts = {
26
+ cwd: dirname(file),
27
+ stdio: ['ignore', output, output],
28
+ env,
29
+ };
30
+ const up = [
31
+ ...compose,
32
+ 'up',
33
+ '--abort-on-container-failure',
34
+ '--no-color',
35
+ '--remove-orphans',
36
+ ];
37
+ const child = spawn('docker', up, opts);
16
38
  const stop = () => {
17
- if (stopCompose !== stop)
39
+ if (stopRef !== stop)
18
40
  return;
19
- stopCompose = undefined;
20
- process.off('SIGINT', onSigInt);
21
- process.off('SIGTERM', onSigTerm);
22
- run(file, ['down'], 'Failed to stop Docker Compose');
41
+ stopRef = undefined;
42
+ child.kill();
43
+ const down = [...compose, 'down', '--remove-orphans'];
44
+ spawnSync('docker', down, opts);
23
45
  };
24
- run(file, ['up', '-d'], 'Failed to start Docker Compose');
25
- stopCompose = stop;
26
- process.off('SIGINT', onSigInt);
27
- process.off('SIGTERM', onSigTerm);
28
- process.once('SIGINT', onSigInt);
29
- process.once('SIGTERM', onSigTerm);
46
+ stopRef = stop;
30
47
  return stop;
31
48
  }
32
- function run(file, args, message) {
33
- const result = spawnSync('docker', ['compose', '-f', file, ...args], {
34
- cwd: dirname(file),
35
- stdio: 'inherit',
36
- });
37
- if (result.error)
38
- throw result.error;
39
- if (result.status !== 0)
40
- throw new Error(message);
41
- }
42
- function onSigInt() {
43
- try {
44
- stopCompose?.();
45
- }
46
- finally {
47
- process.exit(130);
48
- }
49
- }
50
- function onSigTerm() {
51
- try {
52
- stopCompose?.();
53
- }
54
- finally {
55
- process.exit(143);
56
- }
57
- }
58
49
 
50
+ const CACHE_HOME = process.env.XDG_CACHE_HOME || join(homedir(), '.cache');
59
51
  async function ensureCerts({ certs, hostname }) {
60
- const cert = join(certs, 'tls.crt');
61
- const key = join(certs, 'tls.key');
62
- if (existsSync(cert) && existsSync(key))
63
- return;
52
+ const CAROOT = join(CACHE_HOME, 'visage/ca');
53
+ mkdirSync(CAROOT, { recursive: true, mode: 0o700 });
54
+ chmodSync(CAROOT, 0o700);
64
55
  const mkcert = await ensureMkCert();
65
- const env = {
66
- ...process.env,
67
- CAROOT: join(process.env.XDG_CACHE_HOME || join(homedir(), '.cache'), 'visage/ca'),
68
- TRUST_STORES: process.env.TRUST_STORES ?? 'system',
69
- };
70
- mkdirSync(env.CAROOT, { recursive: true, mode: 0o700 });
71
- chmodSync(env.CAROOT, 0o700);
72
- // mkcert -install is idempotent; CA files alone do not prove trust-store state.
73
- {
74
- const result = spawnSync(mkcert, ['-install'], {
75
- env,
76
- stdio: [process.stdin.isTTY ? 'inherit' : 'ignore', 'inherit', 'inherit'],
77
- });
56
+ const logs = join(dirname(certs), 'logs');
57
+ mkdirSync(logs, { recursive: true });
58
+ const log = join(logs, 'mkcert.log');
59
+ const output = openSync(log, 'w');
60
+ const env = { CAROOT, TRUST_STORES: 'system', ...process.env };
61
+ const tty = process.stdin.isTTY;
62
+ const stdio = [
63
+ tty ? 'inherit' : 'ignore',
64
+ output,
65
+ output,
66
+ ];
67
+ if (process.env.CI !== 'true') {
68
+ // mkcert -install is idempotent; CA files alone do not prove trust-store state.
69
+ const result = spawnSync(mkcert, ['-install'], { env, stdio });
78
70
  if (result.error)
79
71
  throw result.error;
80
72
  if (result.status !== 0) {
81
73
  throw new Error('Failed to install CA');
82
74
  }
83
75
  }
84
- // generate certs
76
+ const cert = join(certs, 'tls.crt');
77
+ const key = join(certs, 'tls.key');
85
78
  mkdirSync(certs, { recursive: true });
79
+ rmSync(cert, { force: true });
80
+ rmSync(key, { force: true });
86
81
  const names = [...new Set([hostname, 'localhost', '127.0.0.1', '::1'])];
87
82
  const args = ['-cert-file', cert, '-key-file', key, ...names];
88
- const result = spawnSync(mkcert, args, { env, stdio: 'inherit' });
83
+ const result = spawnSync(mkcert, args, { env, stdio });
89
84
  if (result.error)
90
85
  throw result.error;
91
86
  if (result.status !== 0) {
@@ -93,7 +88,7 @@ async function ensureCerts({ certs, hostname }) {
93
88
  }
94
89
  }
95
90
  async function ensureMkCert() {
96
- const bin = join(process.env.XDG_CACHE_HOME || join(homedir(), '.cache'), 'visage/bin');
91
+ const bin = join(CACHE_HOME, 'visage/bin');
97
92
  const file = join(bin, `mkcert-${process.platform}-${process.arch}`);
98
93
  if (existsSync(file))
99
94
  return file;
@@ -254,6 +249,9 @@ http {
254
249
  ssl_certificate <%~ it.ssl.cert %>;
255
250
  ssl_certificate_key <%~ it.ssl.key %>;
256
251
 
252
+ # Redirect accidental plaintext HTTP requests sent to the HTTPS port.
253
+ error_page 497 =301 https://$http_host$request_uri;
254
+
257
255
  <%_ for (const [name, upstream] of Object.entries(it.upstreams)) { %>
258
256
  <%_ for (const [path, location] of Object.entries(upstream.locations ?? {})) { %>
259
257
  location <%~ path %> {
@@ -334,6 +332,8 @@ function renderOauth2ProxyConfig(config) {
334
332
  cookie_httponly: true,
335
333
  cookie_secure: true,
336
334
  cookie_samesite: 'lax',
335
+ cookie_csrf_per_request: true,
336
+ cookie_csrf_per_request_limit: 16,
337
337
  email_domains: ['*'],
338
338
  scope: config.oauth2.scopes.join(' '),
339
339
  upstreams: ['static://202'],
@@ -342,6 +342,7 @@ function renderOauth2ProxyConfig(config) {
342
342
  pass_access_token: true,
343
343
  pass_authorization_header: true,
344
344
  skip_provider_button: true,
345
+ whitelist_domains: [config.host, `${config.host}:${config.port}`],
345
346
  };
346
347
  return `${Object.entries(data)
347
348
  .map(([key, value]) => {
@@ -409,11 +410,7 @@ const BaseOauth2ProxyUpstream = {
409
410
  '/oauth2/': {
410
411
  auth: { enabled: false },
411
412
  headers: {
412
- Cookie: '$http_cookie',
413
- Host: '$host',
414
- 'X-Real-IP': '$remote_addr',
415
- 'X-Forwarded-For': '$proxy_add_x_forwarded_for',
416
- 'X-Forwarded-Proto': '$scheme',
413
+ Cookie: '$http_cookie', // Forward session cookie.
417
414
  'X-Auth-Request-Redirect': '$request_uri',
418
415
  },
419
416
  },
@@ -461,19 +458,17 @@ function resolveOptions(options) {
461
458
  const { host = 'localhost', port = 9001, cookie = {}, oauth2 = {} } = options;
462
459
  const cookieName = cookie.name ?? 'session';
463
460
  const publicClient = oauth2.clientSecret === null;
464
- const upstreams = {
465
- ...resolveServiceUpstreams(options.services),
466
- ...resolveUpstreams(options.upstreams),
467
- };
461
+ const services = resolveServicesOptions(options.services);
462
+ const upstreams = resolveUpstreamsOptions(services, options.upstreams);
468
463
  return {
469
464
  host,
470
465
  port,
471
466
  cookie: {
472
467
  ...DefaultCookiePolicy,
473
468
  cookie_name: cookie.domains === undefined
474
- ? cookieName.startsWith('__HOST-')
469
+ ? cookieName.startsWith('__Host-')
475
470
  ? cookieName
476
- : `__HOST-${cookieName}`
471
+ : `__Host-${cookieName}`
477
472
  : cookieName,
478
473
  ...(cookie.expire === undefined ? {} : { cookie_expire: cookie.expire }),
479
474
  ...(cookie.refresh === undefined
@@ -493,62 +488,61 @@ function resolveOptions(options) {
493
488
  scopes: oauth2.scopes ?? DefaultOAuth2Client.scopes,
494
489
  public: publicClient,
495
490
  },
496
- services: {
497
- ...Object.fromEntries(Object.entries(options.services ?? {}).map(([name, service]) => [
498
- name,
499
- resolveService(service),
500
- ])),
501
- nginx: {
502
- ...BaseServiceNginx,
503
- ...{
504
- ...resolveService(options.services?.nginx ?? {}),
505
- extra_hosts: [
506
- ...BaseServiceNginx.extra_hosts,
507
- ...(options.services?.nginx?.extra_hosts ?? []),
508
- ],
509
- },
491
+ services,
492
+ upstreams,
493
+ };
494
+ }
495
+ function resolveServicesOptions(services = {}) {
496
+ return {
497
+ ...services,
498
+ nginx: {
499
+ ...BaseServiceNginx,
500
+ ...{
501
+ ...(services.nginx ?? {}),
502
+ extra_hosts: [
503
+ ...BaseServiceNginx.extra_hosts,
504
+ ...(services.nginx?.extra_hosts ?? []),
505
+ ],
510
506
  },
511
- oauth2_proxy: {
512
- ...BaseOAuth2ProxyService,
513
- ...{
514
- ...resolveService(options.services?.oauth2_proxy ?? {}),
515
- extra_hosts: [
516
- ...BaseOAuth2ProxyService.extra_hosts,
517
- ...(options.services?.oauth2_proxy?.extra_hosts ?? []),
518
- ],
519
- },
507
+ },
508
+ oauth2_proxy: {
509
+ ...BaseOAuth2ProxyService,
510
+ ...{
511
+ ...(services.oauth2_proxy ?? {}),
512
+ extra_hosts: [
513
+ ...BaseOAuth2ProxyService.extra_hosts,
514
+ ...(services.oauth2_proxy?.extra_hosts ?? []),
515
+ ],
520
516
  },
521
517
  },
522
- ...(Object.keys(upstreams).length === 0 ? {} : { upstreams }),
523
518
  };
524
519
  }
525
- function resolveService(service) {
526
- const { upstream: _upstream, ...resolved } = service;
527
- return resolved;
528
- }
529
- function resolveServiceUpstreams(services = {}) {
530
- return Object.fromEntries(Object.entries(services)
531
- .filter(([name]) =>
532
- // Exclude base services handled separately.
533
- name !== 'dex' && name !== 'nginx' && name !== 'oauth2_proxy')
534
- .map(([name, service]) => [
535
- name,
536
- resolveUpstream(name, service.upstream ?? {}),
537
- ]));
538
- }
539
- function resolveUpstreams(upstreams = {}) {
540
- return Object.fromEntries(Object.entries(upstreams).map(([name, upstream]) => [
541
- name,
542
- resolveUpstream(name, upstream),
543
- ]));
544
- }
545
- function resolveUpstream(name, upstream) {
520
+ function resolveUpstreamsOptions(services, upstreams = {}) {
521
+ function resolveUpstream(name, upstream) {
522
+ return {
523
+ ...upstream,
524
+ scheme: upstream.scheme,
525
+ host: upstream.host ?? name,
526
+ port: upstream.port ?? (upstream.scheme === 'https' ? 443 : 80),
527
+ locations: upstream.locations ?? { [`/${name}/`]: {} },
528
+ };
529
+ }
546
530
  return {
547
- ...upstream,
548
- host: upstream.host ?? name,
549
- locations: upstream.locations ?? { [`/${name}/`]: {} },
550
- port: upstream.port ?? 80,
551
- scheme: upstream.scheme ?? 'http',
531
+ ...Object.fromEntries(Object.entries(services)
532
+ .filter(([name]) =>
533
+ // Exclude base services handled separately.
534
+ name !== 'dex' && name !== 'nginx' && name !== 'oauth2_proxy')
535
+ .map(([name, service]) => [
536
+ name,
537
+ resolveUpstream(name, { scheme: 'http', ...service.upstream }),
538
+ ])),
539
+ ...Object.fromEntries(Object.entries(upstreams).map(([name, upstream]) => [
540
+ name,
541
+ resolveUpstream(name, {
542
+ scheme: services[name] === undefined ? 'https' : 'http',
543
+ ...upstream,
544
+ }),
545
+ ])),
552
546
  };
553
547
  }
554
548
  function resolveIdpOption(idp) {
@@ -605,6 +599,7 @@ function resolveExternalIdpUpstream(idp) {
605
599
  const issuer = new URL(idp.issuer);
606
600
  return {
607
601
  host: issuer.hostname,
602
+ locations: {},
608
603
  scheme: issuer.protocol === 'https:' ? 'https' : 'http',
609
604
  port: Number(issuer.port) || (issuer.protocol === 'https:' ? 443 : 80),
610
605
  };
@@ -643,27 +638,47 @@ function resolveConfig(options, config, vitePort) {
643
638
  depends_on: ['dex'],
644
639
  },
645
640
  }),
646
- ...options.services,
641
+ ...Object.fromEntries(Object.entries(options.services).map(([name, { upstream: _upstream, ...service }]) => [name, service])),
647
642
  },
648
- upstreams: Object.fromEntries(Object.entries(upstreams).map(([name, upstream]) => [
649
- name,
650
- {
651
- ...upstream,
652
- locations: Object.fromEntries(Object.entries(upstream.locations ?? {}).map(([path, policy]) => [
653
- path,
654
- {
655
- auth: { ...DefaultProxyPolicy.auth, ...policy.auth },
656
- headers: { ...DefaultProxyPolicy.headers, ...policy.headers },
657
- },
658
- ])),
659
- },
660
- ])),
643
+ upstreams: Object.fromEntries(Object.entries(upstreams).map(([name, upstream]) => {
644
+ const external = options.upstreams[name] !== undefined &&
645
+ options.services[name] === undefined;
646
+ return [
647
+ name,
648
+ {
649
+ ...upstream,
650
+ locations: Object.fromEntries(Object.entries(upstream.locations ?? {}).map(([path, policy]) => [
651
+ path,
652
+ {
653
+ auth: { ...DefaultProxyPolicy.auth, ...policy.auth },
654
+ headers: {
655
+ ...(external
656
+ ? { ...DefaultProxyPolicy.headers, Host: upstream.host }
657
+ : DefaultProxyPolicy.headers),
658
+ ...policy.headers,
659
+ },
660
+ },
661
+ ])),
662
+ },
663
+ ];
664
+ })),
661
665
  };
662
666
  }
663
667
 
668
+ function formatUrl(host, port) {
669
+ const AnsiGreen = '\x1b[32m';
670
+ const AnsiCyan = '\x1b[36m';
671
+ const AnsiBold = '\x1b[1m';
672
+ const AnsiReset = '\x1b[0m';
673
+ return ` ${AnsiGreen}➜${AnsiReset} ${AnsiBold}Visage${AnsiReset}: ${AnsiCyan}https://${host}:${AnsiBold}${port}${AnsiReset}${AnsiCyan}/${AnsiReset}`;
674
+ }
664
675
  function visage(options = {}) {
665
676
  const resolvedOptions = resolveOptions(options);
666
677
  let stop;
678
+ const closeBundle = () => {
679
+ stop?.();
680
+ stop = undefined;
681
+ };
667
682
  return {
668
683
  name: 'visage',
669
684
  apply: 'serve',
@@ -680,8 +695,17 @@ function visage(options = {}) {
680
695
  };
681
696
  },
682
697
  configureServer(server) {
698
+ let url;
699
+ const printUrls = server.printUrls.bind(server);
700
+ server.printUrls = () => {
701
+ printUrls();
702
+ if (url)
703
+ server.config.logger.info(formatUrl(url.host, url.port));
704
+ };
683
705
  async function startVisage(port) {
684
706
  const config = resolveConfig(resolvedOptions, server.config, port);
707
+ url = { host: config.host, port: config.port };
708
+ rmSync(join(config.cache, 'logs'), { recursive: true, force: true });
685
709
  await ensureCerts({
686
710
  certs: join(config.cache, config.files.certs[0]),
687
711
  hostname: config.host,
@@ -698,13 +722,11 @@ function visage(options = {}) {
698
722
  throw new Error('Failed to resolve port for Visage');
699
723
  }
700
724
  stop = await startVisage(address.port);
725
+ server.httpServer?.once('close', closeBundle);
701
726
  return result;
702
727
  };
703
728
  },
704
- closeBundle() {
705
- stop?.();
706
- stop = undefined;
707
- },
729
+ closeBundle,
708
730
  };
709
731
  }
710
732
 
@@ -1 +1 @@
1
- {"version":3,"file":"nginx.d.ts","sourceRoot":"","sources":["../../src/render/nginx.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAuD9C,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAI3D"}
1
+ {"version":3,"file":"nginx.d.ts","sourceRoot":"","sources":["../../src/render/nginx.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AA0D9C,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAI3D"}
package/dist/types.d.ts CHANGED
@@ -15,7 +15,8 @@ export type VisageOptions = {
15
15
  */
16
16
  readonly port?: number;
17
17
  /**
18
- * Session cookie settings normalized into OAuth2 Proxy configuration.
18
+ * OAuth2 Proxy session cookie settings for name, browser scope, lifetime, and
19
+ * refresh timing.
19
20
  */
20
21
  readonly cookie?: VisageCookiePolicy;
21
22
  /**
@@ -38,37 +39,48 @@ export type VisageOptions = {
38
39
  readonly upstreams?: Record<string, VisageUpstream>;
39
40
  };
40
41
  /**
41
- * Cookie lifetime, scope, and naming policy for the OAuth2 Proxy session.
42
+ * Settings for the browser session cookie managed by OAuth2 Proxy.
43
+ *
44
+ * OAuth2 Proxy keeps OIDC session state behind this cookie. The cookie lifetime
45
+ * caps the browser session, while the refresh interval controls when OAuth2
46
+ * Proxy tries to renew token state with the provider.
42
47
  */
43
48
  export type VisageCookiePolicy = {
44
49
  /**
45
- * Session cookie name. Host-only cookies are automatically prefixed with
46
- * `__HOST-` when no domains are configured, so the default rendered
47
- * host-only cookie name is `__HOST-session`.
50
+ * Browser session cookie base name. When no domains are configured, Visage
51
+ * renders a host-only name with a `__Host-` prefix, so the default rendered
52
+ * name is `__Host-session`.
48
53
  *
49
54
  * @defaultValue `'session'`
50
55
  */
51
56
  readonly name?: string;
52
57
  /**
53
- * Maximum cookie lifetime using an OAuth2 Proxy duration string.
58
+ * Maximum browser session lifetime. Rendered as OAuth2 Proxy `cookie_expire`
59
+ * using its duration syntax. Keep this aligned with the identity provider's
60
+ * refresh-token lifetime to avoid sessions that can no longer be renewed
61
+ * silently.
54
62
  *
55
63
  * @defaultValue `'8h'`
56
64
  */
57
65
  readonly expire?: string;
58
66
  /**
59
- * Interval after which OAuth2 Proxy refreshes the session using an OAuth2
60
- * Proxy duration string.
67
+ * Session age after which OAuth2 Proxy attempts silent renewal using the
68
+ * stored refresh token, when one is available. Rendered as `cookie_refresh`
69
+ * using OAuth2 Proxy duration syntax. If upstreams validate forwarded access
70
+ * tokens, set this below the access-token lifetime so OAuth2 Proxy refreshes
71
+ * before forwarding an expired bearer token.
61
72
  *
62
73
  * @defaultValue `'15m'`
63
74
  */
64
75
  readonly refresh?: string;
65
76
  /**
66
- * Cookie domains for sharing the session across local hostnames. Leave unset
67
- * for a host-only cookie.
77
+ * Cookie domains for sharing one session across hostnames. Omit for a
78
+ * host-only cookie.
68
79
  */
69
80
  readonly domains?: readonly string[];
70
81
  /**
71
- * Cookie path scope.
82
+ * Cookie path scope. Keep broad enough for every protected route that should
83
+ * send the session.
72
84
  *
73
85
  * @defaultValue `'/'`
74
86
  */
@@ -139,11 +151,15 @@ export type VisageDexExpiry = {
139
151
  export type VisageDexUser = {
140
152
  /**
141
153
  * Email address used as the Dex login identifier.
154
+ *
155
+ * @defaultValue `'user@example.com'`
142
156
  */
143
157
  readonly email: string;
144
158
  /**
145
159
  * Plain-text development password. Visage hashes this before rendering the
146
160
  * Dex config.
161
+ *
162
+ * @defaultValue `'pass'`
147
163
  */
148
164
  readonly password: string;
149
165
  /**
@@ -254,13 +270,13 @@ export type VisageUpstream = {
254
270
  /**
255
271
  * URL scheme NGINX should use when proxying to this upstream.
256
272
  *
257
- * @defaultValue `'http'`
273
+ * @defaultValue `'https'` for external upstreams; `'http'` otherwise.
258
274
  */
259
275
  readonly scheme?: 'http' | 'https';
260
276
  /**
261
277
  * Port NGINX should proxy to on {@link VisageUpstream.host}.
262
278
  *
263
- * @defaultValue `80`
279
+ * @defaultValue `80`, or `443` when {@link VisageUpstream.scheme} is `'https'`.
264
280
  */
265
281
  readonly port?: number;
266
282
  /**
@@ -304,7 +320,8 @@ export type VisageProxyPolicy = {
304
320
  * Request headers to set when proxying to the upstream. Values may include
305
321
  * NGINX variables. These are merged with Visage's default proxy headers:
306
322
  * `Cookie`, `Host`, `X-Real-IP`, `X-Forwarded-For`, and
307
- * `X-Forwarded-Proto`.
323
+ * `X-Forwarded-Proto`. `Host` defaults to the upstream host for top-level
324
+ * upstreams with no matching service, and to `$host` otherwise.
308
325
  */
309
326
  readonly headers?: {
310
327
  readonly [key: string]: string;
@@ -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,wBAAwB,CAAC;IAC3D;;OAEG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,kBAAkB,CAAC;IACrC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAClD;;OAEG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CACrD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;OAEG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC;IAClC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;CAC3C,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B;;OAEG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;;OAEG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;OAEG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE;QACvB;;WAEG;QACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;QACpC;;WAEG;QACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;QACnC;;WAEG;QACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;QACnC;;WAEG;QACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;KACjC,CAAC;CACH,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;;OAOG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;OAEG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC;;OAEG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC;;OAEG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE;QAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAAA;KAAE,CAAC;CACrE,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;OAEG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE;QACd;;;;WAIG;QACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAC3B;;;;WAIG;QACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;QAC5B;;;;;WAKG;QACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;KAC5B,CAAC;IACF;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CACvD,CAAC"}
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;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,kBAAkB,CAAC;IACrC;;;OAGG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,gBAAgB,GAAG,wBAAwB,CAAC;IAC3D;;OAEG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,kBAAkB,CAAC;IACrC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAClD;;OAEG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CACrD,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;OAEG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC;IAClC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;CAC3C,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B;;OAEG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;;OAEG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;OAEG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE;QACvB;;WAEG;QACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;QACpC;;WAEG;QACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;QACnC;;WAEG;QACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;QACnC;;WAEG;QACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;KACjC,CAAC;CACH,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;;OAOG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;OAEG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC;;OAEG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC;;OAEG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE;QAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAAA;KAAE,CAAC;CACrE,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;OAEG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE;QACd;;;;WAIG;QACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAC3B;;;;WAIG;QACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;QAC5B;;;;;WAKG;QACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;KAC5B,CAAC;IACF;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CACvD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blakearoberts/visage",
3
- "version": "0.0.1-rc.6",
3
+ "version": "0.0.1-rc.8",
4
4
  "description": "Vite plugin for local development with HMR and OIDC session cookie lifecycle semantics.",
5
5
  "type": "module",
6
6
  "author": "Blake Roberts",
@@ -14,14 +14,15 @@
14
14
  },
15
15
  "homepage": "https://github.com/blakearoberts/visage#readme",
16
16
  "keywords": [
17
- "vite",
18
- "plugin",
19
- "oidc",
17
+ "authentication",
20
18
  "hmr",
21
- "session",
22
- "cookie",
23
- "lifecycle",
24
- "development"
19
+ "local-development",
20
+ "oauth2",
21
+ "oidc",
22
+ "pkce",
23
+ "session-cookie",
24
+ "vite",
25
+ "vite-plugin"
25
26
  ],
26
27
  "main": "dist/index.js",
27
28
  "types": "dist/index.d.ts",
@@ -44,11 +45,14 @@
44
45
  "scripts": {
45
46
  "build": "npm run clean && rollup -c",
46
47
  "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
47
- "test": "npm run test:unit",
48
+ "dev:example": "cd examples/managed-service && npm run dev",
49
+ "format": "prettier --write \"{docs,examples,src,test}/**/*.{ts,tsx,js,jsx,json,css,html,md}\" \"*.{json,md}\"",
50
+ "format:check": "prettier --check \"{docs,examples,src,test}/**/*.{ts,tsx,js,jsx,json,css,html,md}\" \"*.{json,md}\"",
51
+ "test": "npm run typecheck && npm run test:unit",
52
+ "test:all": "npm test && npm run test:e2e",
48
53
  "test:e2e": "playwright test test/e2e",
49
54
  "test:unit": "node --experimental-strip-types --test test/unit/*.test.ts",
50
- "format": "prettier --write \"{docs,examples,src,test}/**/*.{ts,tsx,js,jsx,json,css,html,md}\" \"*.{json,md}\"",
51
- "format:check": "prettier --check \"{docs,examples,src,test}/**/*.{ts,tsx,js,jsx,json,css,html,md}\" \"*.{json,md}\""
55
+ "typecheck": "tsc --noEmit && tsc -p tsconfig.test.json"
52
56
  },
53
57
  "devDependencies": {
54
58
  "@playwright/test": "^1.59.1",