@nubisco/openbridge 0.32.4 → 0.34.0

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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=avatar-claim.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avatar-claim.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/avatar-claim.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,47 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { acceptPictureClaim } from '../auth.js';
3
+ const ISSUER = 'https://platform.nubisco.io';
4
+ const GOOD = `${ISSUER}/api/avatars/3f9c0a1e5b7d4c2a8e6f1b0d9c3a7e52`;
5
+ describe('acceptPictureClaim', () => {
6
+ it('keeps an avatar served by the issuer', () => {
7
+ expect(acceptPictureClaim(ISSUER, GOOD)).toBe(GOOD);
8
+ });
9
+ it('keeps it when the issuer was configured with a trailing slash', () => {
10
+ expect(acceptPictureClaim(`${ISSUER}/`, GOOD)).toBe(GOOD);
11
+ });
12
+ it('refuses a URL on another origin', () => {
13
+ // The value becomes an <img src> on every page, so a foreign host would
14
+ // have this app announce the viewer to whoever controls it.
15
+ expect(acceptPictureClaim(ISSUER, 'https://evil.example/api/avatars/abc')).toBeUndefined();
16
+ expect(acceptPictureClaim(ISSUER, 'http://platform.nubisco.io/api/avatars/abc')).toBeUndefined();
17
+ expect(acceptPictureClaim(ISSUER, 'https://platform.nubisco.io.evil.example/api/avatars/abc')).toBeUndefined();
18
+ });
19
+ it('refuses a path outside the avatar service', () => {
20
+ expect(acceptPictureClaim(ISSUER, `${ISSUER}/api/tokens/abc`)).toBeUndefined();
21
+ expect(acceptPictureClaim(ISSUER, `${ISSUER}/`)).toBeUndefined();
22
+ expect(acceptPictureClaim(ISSUER, `${ISSUER}/api/avatars`)).toBeUndefined();
23
+ });
24
+ it('refuses credentials in the URL', () => {
25
+ // No business in an image source, and a sign the value was not built by
26
+ // the platform.
27
+ expect(acceptPictureClaim(ISSUER, 'https://user:pw@platform.nubisco.io/api/avatars/abc')).toBeUndefined();
28
+ expect(acceptPictureClaim(ISSUER, 'https://user@platform.nubisco.io/api/avatars/abc')).toBeUndefined();
29
+ });
30
+ it('treats an absent or empty claim as no avatar', () => {
31
+ // The platform omits the claim entirely for someone with no avatar, so
32
+ // absent means "no avatar" and must clear anything stored, never be read
33
+ // as "unchanged".
34
+ expect(acceptPictureClaim(ISSUER, undefined)).toBeUndefined();
35
+ expect(acceptPictureClaim(ISSUER, '')).toBeUndefined();
36
+ expect(acceptPictureClaim(ISSUER, null)).toBeUndefined();
37
+ expect(acceptPictureClaim(ISSUER, 42)).toBeUndefined();
38
+ });
39
+ it('refuses anything when no issuer is configured', () => {
40
+ expect(acceptPictureClaim(null, GOOD)).toBeUndefined();
41
+ });
42
+ it('refuses a value that is not a URL at all', () => {
43
+ expect(acceptPictureClaim(ISSUER, '/api/avatars/abc')).toBeUndefined();
44
+ expect(acceptPictureClaim(ISSUER, 'not a url')).toBeUndefined();
45
+ });
46
+ });
47
+ //# sourceMappingURL=avatar-claim.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avatar-claim.test.js","sourceRoot":"","sources":["../../src/__tests__/avatar-claim.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=updater.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updater.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/updater.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,67 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { detectInstall, detectRestartStrategy, globalPrefix, PACKAGE_ROOT } from '../updater.js';
3
+ const saved = { ...process.env };
4
+ beforeEach(() => {
5
+ delete process.env.INVOCATION_ID;
6
+ delete process.env.OPENBRIDGE_INSTALL;
7
+ delete process.env.OPENBRIDGE_VERSION_SPEC;
8
+ });
9
+ afterEach(() => {
10
+ process.env = { ...saved };
11
+ });
12
+ describe('detectRestartStrategy', () => {
13
+ it('trusts systemd, which stamps every service it starts', () => {
14
+ process.env.INVOCATION_ID = 'a8f3c2';
15
+ expect(detectRestartStrategy()).toBe('supervisor');
16
+ });
17
+ it('trusts the container restart policy', () => {
18
+ process.env.OPENBRIDGE_INSTALL = 'docker';
19
+ expect(detectRestartStrategy()).toBe('supervisor');
20
+ });
21
+ it('recognises a supervisor name the kernel truncated', () => {
22
+ // /proc/<pid>/comm is capped at fifteen characters and OpenRC's
23
+ // supervise-daemon is sixteen, so it arrives as "supervise-daemo". An exact
24
+ // comparison misses it, the daemon concludes nothing will restart it, and
25
+ // it leaves a process behind to start a replacement while the supervisor
26
+ // starts one too. The second dies on the port the first holds.
27
+ const truncated = 'supervise-daemo';
28
+ const supervisors = ['supervise-daemon', 'systemd', 'runsv', 's6-supervise', 'runit', 'launchd'];
29
+ expect(supervisors.some((n) => n === truncated || n.startsWith(truncated))).toBe(true);
30
+ });
31
+ it('assumes nothing will restart it when it recognises no supervisor', () => {
32
+ // The optimistic answer leaves a stopped daemon and someone locked out, so
33
+ // an unrecognised environment gets the strategy that starts its own
34
+ // replacement rather than the benefit of the doubt.
35
+ expect(detectRestartStrategy()).toBe('spawn');
36
+ });
37
+ });
38
+ describe('detectInstall', () => {
39
+ it('refuses to replace a source checkout, and says why', () => {
40
+ // Tests run from the monorepo, so this is the source case: somebody's
41
+ // working tree, which an update would discard.
42
+ const info = detectInstall();
43
+ expect(info.method).toBe('source');
44
+ expect(info.canSelfUpdate).toBe(false);
45
+ expect(info.blockedBy).toMatch(/source checkout/);
46
+ });
47
+ it('withholds self-update from a pinned deployment, and says why', () => {
48
+ process.env.OPENBRIDGE_INSTALL = 'docker';
49
+ process.env.OPENBRIDGE_VERSION_SPEC = '0.31.1';
50
+ const info = detectInstall();
51
+ expect(info.canSelfUpdate).toBe(false);
52
+ expect(info.blockedBy).toMatch(/pinned to 0\.31\.1/);
53
+ });
54
+ it('allows it for an unpinned container', () => {
55
+ process.env.OPENBRIDGE_INSTALL = 'docker';
56
+ expect(detectInstall().canSelfUpdate).toBe(true);
57
+ });
58
+ });
59
+ describe('globalPrefix', () => {
60
+ it('is null when not installed under a node_modules', () => {
61
+ // A source checkout has no prefix to install into, which is exactly why
62
+ // detectInstall refuses it.
63
+ expect(PACKAGE_ROOT).not.toContain('/node_modules/');
64
+ expect(globalPrefix()).toBeNull();
65
+ });
66
+ });
67
+ //# sourceMappingURL=updater.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updater.test.js","sourceRoot":"","sources":["../../src/__tests__/updater.test.ts"],"names":[],"mappings":"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"}
package/dist/auth.d.ts CHANGED
@@ -18,6 +18,22 @@ export interface TAuthConfig {
18
18
  appId: string | null;
19
19
  secret: Buffer;
20
20
  }
21
+ /**
22
+ * Keep a `picture` claim only when it is an avatar served by our own issuer.
23
+ *
24
+ * The value becomes an `<img src>` on every page, so a token that carried a
25
+ * URL anywhere else would have this app fetch it, announcing the viewer to
26
+ * whoever controls it. Restricting it to the issuer's origin under
27
+ * `/api/avatars/` means the only thing it can point at is the avatar service
28
+ * the token came from. Credentials in the URL are refused outright: they have
29
+ * no business in an image source and are a sign the value was built by
30
+ * something other than the platform.
31
+ *
32
+ * An absent or unusable claim returns undefined, which clears any stored value.
33
+ * The platform omits `picture` entirely for someone with no avatar, so absent
34
+ * means "no avatar" rather than "unchanged".
35
+ */
36
+ export declare function acceptPictureClaim(issuer: string | null, picture: unknown): string | undefined;
21
37
  export declare function loadAuthConfig(): TAuthConfig;
22
38
  export declare function registerAuthRoutes(app: FastifyInstance, config: TAuthConfig): Promise<void>;
23
39
  //# sourceMappingURL=auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAA;AAS9D,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;CACf;AAiCD,wBAAgB,cAAc,IAAI,WAAW,CAS5C;AAkCD,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAqFjG"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAA;AAS9D,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;CACf;AAUD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAc9F;AA2BD,wBAAgB,cAAc,IAAI,WAAW,CAS5C;AAkCD,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAyFjG"}
package/dist/auth.js CHANGED
@@ -17,6 +17,41 @@ import os from 'os';
17
17
  import { PlatformClient } from './platform-client.js';
18
18
  const COOKIE_NAME = 'openbridge_session';
19
19
  const SESSION_TTL_SEC = 7 * 24 * 60 * 60; // 7 days
20
+ /**
21
+ * Keep a `picture` claim only when it is an avatar served by our own issuer.
22
+ *
23
+ * The value becomes an `<img src>` on every page, so a token that carried a
24
+ * URL anywhere else would have this app fetch it, announcing the viewer to
25
+ * whoever controls it. Restricting it to the issuer's origin under
26
+ * `/api/avatars/` means the only thing it can point at is the avatar service
27
+ * the token came from. Credentials in the URL are refused outright: they have
28
+ * no business in an image source and are a sign the value was built by
29
+ * something other than the platform.
30
+ *
31
+ * An absent or unusable claim returns undefined, which clears any stored value.
32
+ * The platform omits `picture` entirely for someone with no avatar, so absent
33
+ * means "no avatar" rather than "unchanged".
34
+ */
35
+ export function acceptPictureClaim(issuer, picture) {
36
+ if (!issuer || typeof picture !== 'string' || picture === '')
37
+ return undefined;
38
+ let url;
39
+ let base;
40
+ try {
41
+ url = new URL(picture);
42
+ base = new URL(issuer);
43
+ }
44
+ catch {
45
+ return undefined;
46
+ }
47
+ if (url.origin !== base.origin)
48
+ return undefined;
49
+ if (!url.pathname.startsWith('/api/avatars/'))
50
+ return undefined;
51
+ if (url.username !== '' || url.password !== '')
52
+ return undefined;
53
+ return url.toString();
54
+ }
20
55
  function getConfigDir() {
21
56
  // The Docker image mounts /root/.openbridge as a persistent volume.
22
57
  // Fall back to the user's home dir for `pnpm dev` runs.
@@ -122,9 +157,13 @@ export async function registerAuthRoutes(app, config) {
122
157
  if (expectedSub && claims.sub !== expectedSub) {
123
158
  return reply.code(409).send({ error: 'subject_mismatch' });
124
159
  }
160
+ // Re-read at every sign-in, so a changed avatar is picked up and a removed
161
+ // one disappears. This session is the only user record OpenBridge keeps.
162
+ const picture = acceptPictureClaim(config.issuer, claims.picture);
125
163
  const payload = {
126
164
  userId: claims.sub,
127
165
  email: claims.email,
166
+ ...(picture ? { picture } : {}),
128
167
  exp: Math.floor(Date.now() / 1000) + SESSION_TTL_SEC,
129
168
  };
130
169
  const cookieValue = signSession(config.secret, payload);
@@ -132,7 +171,7 @@ export async function registerAuthRoutes(app, config) {
132
171
  if (isProductionLike())
133
172
  parts.push('Secure');
134
173
  reply.header('Set-Cookie', parts.join('; '));
135
- return { ok: true, user: { id: claims.sub, email: claims.email } };
174
+ return { ok: true, user: { id: claims.sub, email: claims.email, picture } };
136
175
  });
137
176
  app.get('/auth/me', async (req, reply) => {
138
177
  const cookie = getCookie(req, COOKIE_NAME);
@@ -141,7 +180,7 @@ export async function registerAuthRoutes(app, config) {
141
180
  const session = verifySession(config.secret, cookie);
142
181
  if (!session)
143
182
  return reply.code(401).send({ error: 'unauthenticated' });
144
- return { user: { id: session.userId, email: session.email } };
183
+ return { user: { id: session.userId, email: session.email, picture: session.picture } };
145
184
  });
146
185
  app.post('/auth/logout', async (_req, reply) => {
147
186
  const parts = [`${COOKIE_NAME}=`, 'HttpOnly', 'SameSite=Lax', 'Path=/', 'Max-Age=0'];
package/dist/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,11 @@ export interface TPlatformClientOptions {
16
16
  export interface TJwtClaims {
17
17
  sub: string;
18
18
  email: string;
19
+ /**
20
+ * The platform's avatar URL. Absent, never null or empty, when the person
21
+ * has no avatar, so an absent claim means "no avatar" rather than "unchanged".
22
+ */
23
+ picture?: string;
19
24
  name?: string;
20
25
  role: string;
21
26
  /** App id (uuid) the token was issued to. */
@@ -1 +1 @@
1
- {"version":3,"file":"platform-client.d.ts","sourceRoot":"","sources":["../src/platform-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,sBAAsB;IACrC,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAA;IACd,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,oFAAoF;IACpF,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;CACZ;AA6BD,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,SAAS,CAAsD;IACvE,OAAO,CAAC,YAAY,CAAoC;gBAE5C,OAAO,EAAE,sBAAsB;YAK7B,SAAS;YAaT,YAAY;YAgBZ,SAAS;IAQjB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;CAsBjD"}
1
+ {"version":3,"file":"platform-client.d.ts","sourceRoot":"","sources":["../src/platform-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,sBAAsB;IACrC,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAA;IACd,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,oFAAoF;IACpF,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;CACZ;AA6BD,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,SAAS,CAAsD;IACvE,OAAO,CAAC,YAAY,CAAoC;gBAE5C,OAAO,EAAE,sBAAsB;YAK7B,SAAS;YAaT,YAAY;YAgBZ,SAAS;IAQjB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;CAsBjD"}
@@ -1 +1 @@
1
- {"version":3,"file":"platform-client.js","sourceRoot":"","sources":["../src/platform-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"platform-client.js","sourceRoot":"","sources":["../src/platform-client.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAA;AAa7B,OAAO,KAAK,EAAE,cAAc,EAA4B,MAAM,0BAA0B,CAAA;AAGxF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8CAA8C,CAAA;AASjF,OAAO,EAA4B,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAC3E,OAAO,EAAE,kBAAkB,EAAE,CAAA;AAqC7B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAChE,OAAO,EAGL,KAAK,mBAAmB,EAEzB,MAAM,2BAA2B,CAAA;AAElC,MAAM,WAAW,OAAO;IACtB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAWD,wBAAsB,YAAY,CAChC,QAAQ,EAAE,cAAc,EACxB,MAAM,GAAE,aAAa,GAAG,IAAW,EACnC,OAAO,GAAE,OAAO,GAAG,IAAW,EAC9B,kBAAkB,GAAE,MAAM,EAAO,EACjC,mBAAmB,GAAE,GAAG,CAAC,MAAM,CAAa,EAC5C,QAAQ,GAAE,GAAG,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAa,EAC3E,kBAAkB,GAAE,GAAG,CAAC,MAAM,CAAa,EAC3C,iBAAiB,GAAE,iBAAiB,GAAG,IAAW,EAClD,mBAAmB,GAAE,mBAAmB,GAAG,IAAW;AACtD;;;;GAIG;AACH,sBAAsB,GAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,GAAG,IAAI,CAAC,GAAG,IAAW;AAC5E,4EAA4E;AAC5E,mBAAmB,GAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,IAAW,sSA6qDzE"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAA;AAa7B,OAAO,KAAK,EAAE,cAAc,EAA4B,MAAM,0BAA0B,CAAA;AAGxF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8CAA8C,CAAA;AASjF,OAAO,EAA4B,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAC3E,OAAO,EAAE,kBAAkB,EAAE,CAAA;AAyC7B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAChE,OAAO,EAGL,KAAK,mBAAmB,EAEzB,MAAM,2BAA2B,CAAA;AAElC,MAAM,WAAW,OAAO;IACtB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAWD,wBAAsB,YAAY,CAChC,QAAQ,EAAE,cAAc,EACxB,MAAM,GAAE,aAAa,GAAG,IAAW,EACnC,OAAO,GAAE,OAAO,GAAG,IAAW,EAC9B,kBAAkB,GAAE,MAAM,EAAO,EACjC,mBAAmB,GAAE,GAAG,CAAC,MAAM,CAAa,EAC5C,QAAQ,GAAE,GAAG,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAa,EAC3E,kBAAkB,GAAE,GAAG,CAAC,MAAM,CAAa,EAC3C,iBAAiB,GAAE,iBAAiB,GAAG,IAAW,EAClD,mBAAmB,GAAE,mBAAmB,GAAG,IAAW;AACtD;;;;GAIG;AACH,sBAAsB,GAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,GAAG,IAAI,CAAC,GAAG,IAAW;AAC5E,4EAA4E;AAC5E,mBAAmB,GAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,IAAW,sSA0tDzE"}
package/dist/server.js CHANGED
@@ -17,7 +17,7 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
17
17
  // Version: resolved in version.ts so the CLI can read it without loading this module.
18
18
  import { APP_VOLUME, VERSION_FILE, OPENBRIDGE_VERSION } from './version.js';
19
19
  export { OPENBRIDGE_VERSION };
20
- import { CURRENT_DIR, PACKAGE_NAME, PREVIOUS_DIR, STAGING_DIR, detectInstall, fetchLatestVersion, fetchReleaseNotes, installedVersionAt, npmInstall, releaseUrl, } from './updater.js';
20
+ import { CURRENT_DIR, PACKAGE_NAME, PREVIOUS_DIR, STAGING_DIR, detectInstall, fetchLatestVersion, fetchReleaseNotes, globalPrefix, installedVersionAt, npmInstall, npmInstallGlobal, releaseUrl, restartDaemon, versionOnDisk, } from './updater.js';
21
21
  let updateProgress = { stage: 'idle' };
22
22
  const updateListeners = new Set();
23
23
  // Resolve UI dist: env override → npm layout (../ui-dist) → monorepo dev layout
@@ -97,6 +97,8 @@ nativeAccessoryUuid = null) {
97
97
  // What to run when we cannot do it ourselves, matched to how this
98
98
  // particular deployment was installed.
99
99
  updateCommand: install.command,
100
+ /** Why self-update is unavailable, so the UI can say more than "not available". */
101
+ updateBlockedBy: install.blockedBy ?? null,
100
102
  installMethod: install.method,
101
103
  pinnedTo: install.pinnedTo,
102
104
  releaseUrl: latest ? releaseUrl(latest) : null,
@@ -133,21 +135,63 @@ nativeAccessoryUuid = null) {
133
135
  throw {
134
136
  statusCode: 503,
135
137
  message: install.pinnedTo !== null
136
- ? `This deployment is pinned to ${install.pinnedTo}. Change the pin and recreate the container to move version.`
137
- : `This ${install.method} install cannot update itself. Run: ${install.command}`,
138
+ ? `This deployment is pinned to ${install.pinnedTo}. Change the pin to move version.`
139
+ : `This ${install.method} install cannot update itself (${install.blockedBy}). Run: ${install.command}`,
138
140
  };
139
141
  }
142
+ function broadcast(msg) {
143
+ updateProgress = msg;
144
+ for (const listener of updateListeners)
145
+ listener(msg);
146
+ }
147
+ // An npm install replaces itself in place. There is no staging tree to swap,
148
+ // because the package directory is the only copy and overwriting it while
149
+ // the daemon runs is safe: what it is executing is already in memory.
150
+ if (install.method === 'npm') {
151
+ const prefix = globalPrefix();
152
+ if (!prefix)
153
+ throw { statusCode: 503, message: 'Could not determine the npm prefix to install into' };
154
+ (async () => {
155
+ try {
156
+ broadcast({ stage: 'downloading', progress: 0, message: 'Checking npm for the latest version...' });
157
+ const version = await fetchLatestVersion();
158
+ if (!version)
159
+ throw new Error('Could not resolve the latest version from the npm registry');
160
+ if (version === OPENBRIDGE_VERSION) {
161
+ broadcast({ stage: 'idle', message: `Already on v${version}` });
162
+ return;
163
+ }
164
+ log.info(`Self-update: installing ${PACKAGE_NAME}@${version} into ${prefix}...`);
165
+ broadcast({ stage: 'downloading', message: `Installing v${version} from npm...`, version });
166
+ await npmInstallGlobal(prefix, version, (line) => {
167
+ if (line)
168
+ log.debug(`npm: ${line}`);
169
+ });
170
+ // Only believe it once the new version is on disk. A failed install
171
+ // must leave the daemon running the old code, not exit into nothing.
172
+ const onDisk = versionOnDisk();
173
+ if (onDisk !== version) {
174
+ throw new Error(`Install finished but the package reports ${onDisk ?? 'no version'}, expected ${version}`);
175
+ }
176
+ log.info(`Update to v${version} installed: restarting to pick it up...`);
177
+ broadcast({ stage: 'restarting', message: `Restarting with v${version}...`, version });
178
+ restartDaemon(install.restart ?? 'spawn', (m) => log.info(m));
179
+ }
180
+ catch (err) {
181
+ // Nothing was swapped, so the running daemon is untouched and the old
182
+ // version stays installed.
183
+ log.error(`Self-update failed: ${err.message}`);
184
+ broadcast({ stage: 'error', message: err.message });
185
+ }
186
+ })();
187
+ return { updating: true };
188
+ }
140
189
  try {
141
190
  mkdirSync(STAGING_DIR, { recursive: true });
142
191
  }
143
192
  catch {
144
193
  throw { statusCode: 503, message: 'Update volume not available. Mount /opt/openbridge as a Docker volume.' };
145
194
  }
146
- function broadcast(msg) {
147
- updateProgress = msg;
148
- for (const listener of updateListeners)
149
- listener(msg);
150
- }
151
195
  // Run update async: respond immediately
152
196
  ;
153
197
  (async () => {