@k2b/cloud 0.9.0 → 0.9.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@k2b/cloud",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "description": "Application platform library for independently deployed Hono and SolidJS services behind a dynamic gateway.",
5
5
  "license": "AGPL-3.0-or-later",
6
6
  "repository": {
@@ -98,7 +98,7 @@
98
98
  "@tailwindcss/typography": "0.5.20",
99
99
  "@k2b/nessi": "0.12.0",
100
100
  "@k2b/ssr": "0.14.0",
101
- "@k2b/ui": "0.4.1",
101
+ "@k2b/ui": "0.4.2",
102
102
  "@k2b/stdlib": "0.25.0",
103
103
  "@k2b/sync": "6.4.0",
104
104
  "@nats-io/transport-node": "3.4.0",
@@ -5,10 +5,14 @@ import { env } from "../config/env";
5
5
  /** Set by `scripts/build.ts`; the bundle lives next to `dist/assets/`. */
6
6
  declare const __CLOUD_APP_ASSETS__: string | undefined;
7
7
 
8
+ // `resolve` normalizes both forms: a file URL keeps its trailing slash, which
9
+ // would otherwise break the containment check below (`/app/assets//...`).
8
10
  const assetsRoot = (): string =>
9
- typeof __CLOUD_APP_ASSETS__ === "string"
10
- ? fileURLToPath(new URL(__CLOUD_APP_ASSETS__, import.meta.url))
11
- : resolve(env.APP_DIR ?? process.cwd(), "src/assets");
11
+ resolve(
12
+ typeof __CLOUD_APP_ASSETS__ === "string"
13
+ ? fileURLToPath(new URL(__CLOUD_APP_ASSETS__, import.meta.url))
14
+ : resolve(env.APP_DIR ?? process.cwd(), "src/assets"),
15
+ );
12
16
 
13
17
  /**
14
18
  * Absolute path of a server-side application asset.
@@ -457,7 +457,6 @@ export const accountLifecycle = {
457
457
  });
458
458
  await tx`DELETE FROM auth.users WHERE id = ${userId}::uuid`;
459
459
  });
460
- await session.revokeAllForUser(userId);
461
460
  summary.changed += 1;
462
461
  } catch (error) {
463
462
  summary.failed += 1;
@@ -507,7 +506,6 @@ export const accountLifecycle = {
507
506
  });
508
507
  await tx`DELETE FROM auth.users WHERE id = ${userId}::uuid`;
509
508
  });
510
- await session.revokeAllForUser(userId);
511
509
  summary.changed += 1;
512
510
  } catch (error) {
513
511
  summary.failed += 1;
@@ -847,7 +847,7 @@ export const deleteUser = async (params: {
847
847
  });
848
848
  throw dbError;
849
849
  }
850
- await session.revokeAllForUser(id);
850
+ // Deleting the row invalidates every session; no epoch bump is possible or needed.
851
851
 
852
852
  return { ok: true, data: undefined };
853
853
  };
@@ -8,7 +8,6 @@ import { writeLocalAccount } from "../../accounts/posix";
8
8
  import type { AuditActor } from "../../audit";
9
9
  import { generateUniqueAbbreviation } from "../../ipa/users";
10
10
  import { isUniqueViolation } from "../../postgres";
11
- import { session } from "../../session";
12
11
  import * as settings from "../../settings";
13
12
 
14
13
  type DbRow = Record<string, unknown>;
@@ -265,8 +264,8 @@ export const remove = async (params: { id: string; actor: { userId: string; uid:
265
264
  });
266
265
  await tx`DELETE FROM auth.users WHERE id = ${params.id}::uuid`;
267
266
  });
268
-
269
- await session.revokeAllForUser(params.id);
267
+ // Deleting the row invalidates every session: session lookups find no user.
268
+ // A separate epoch bump would fail because the row is gone.
270
269
 
271
270
  return { ok: true, data: undefined };
272
271
  };
@@ -32,11 +32,13 @@ function MobileNavigation(props: {
32
32
  );
33
33
  return (
34
34
  <BottomSheet onDismiss={props.dismiss}>
35
- <BottomSheet.Header
36
- title={workspace()?.label || t().apps}
37
- close={() => void props.dismiss()}
38
- actions={
39
- <Show when={workspace()} fallback={<span class="font-semibold">{t().allApps}</span>}>
35
+ {/* Without an app menu the launchpad gets the whole sheet; the hidden
36
+ heading still names the dialog, and the handle and backdrop dismiss it. */}
37
+ <Show when={workspace()} fallback={<h2 class="sr-only">{t().allApps}</h2>}>
38
+ <BottomSheet.Header
39
+ title={workspace()?.label || t().apps}
40
+ close={() => void props.dismiss()}
41
+ actions={
40
42
  <SegmentedControl
41
43
  class="cloud-mobile-menu__switch"
42
44
  size="md"
@@ -48,9 +50,9 @@ function MobileNavigation(props: {
48
50
  { value: "apps", label: t().allApps },
49
51
  ]}
50
52
  />
51
- </Show>
52
- }
53
- />
53
+ }
54
+ />
55
+ </Show>
54
56
  <BottomSheet.Body>
55
57
  <Show
56
58
  when={workspace() && tab() === "app"}