@ibgib/space-gib 0.0.19 → 0.0.21

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,208 @@
1
+ /**
2
+ * generate-privacy-html.js
3
+ *
4
+ * Build-time script that reads canonical `docs/PRIVACY_POLICY.md` and generates
5
+ * a styled, standalone `src/client/privacy.html` page for space-gib using `@ibgib/helper-gib`.
6
+ *
7
+ * Run: node generate-privacy-html.js
8
+ */
9
+
10
+ import * as pathUtils from 'path';
11
+ import { readFile, writeFile } from 'node:fs/promises';
12
+ import { fileURLToPath } from 'node:url';
13
+
14
+ import { convertMarkdownToHtml } from '@ibgib/helper-gib/dist/helpers/markdown-helper.mjs';
15
+
16
+ const __filename = fileURLToPath(import.meta.url);
17
+ const __dirname = pathUtils.dirname(__filename);
18
+
19
+ const lc = `[${import.meta.url}]`;
20
+ console.log(`${lc} starting...`);
21
+
22
+ const privacyMdPath = pathUtils.resolve(__dirname, '../../docs/PRIVACY_POLICY.md');
23
+ const outputHtmlPath = pathUtils.resolve(__dirname, './src/client/privacy.html');
24
+
25
+ const mdContent = await readFile(privacyMdPath, { encoding: 'utf8' });
26
+
27
+ const bodyHtml = convertMarkdownToHtml(mdContent, { linkTarget: '_blank', linkRel: 'noopener' });
28
+
29
+ const fullHtml = `<!DOCTYPE html>
30
+ <html lang="en-US">
31
+ <head>
32
+ <meta charset="utf-8" />
33
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
34
+ <title>Privacy Policy · ibgib.space</title>
35
+ <link rel="stylesheet" type="text/css" href="/style.css">
36
+ <style>
37
+ html, body {
38
+ height: auto !important;
39
+ min-height: 100% !important;
40
+ overflow-y: auto !important;
41
+ overflow-x: hidden !important;
42
+ }
43
+ body {
44
+ background: #11111b;
45
+ color: #cdd6f4;
46
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
47
+ margin: 0;
48
+ padding: 0;
49
+ line-height: 1.6;
50
+ }
51
+ .page-container {
52
+ max-width: 860px;
53
+ margin: 0 auto;
54
+ padding: 2.5rem 1.5rem 4rem;
55
+ }
56
+ .header-bar {
57
+ display: flex;
58
+ align-items: center;
59
+ justify-content: space-between;
60
+ padding-bottom: 1.5rem;
61
+ margin-bottom: 2rem;
62
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
63
+ }
64
+ .brand-link {
65
+ color: #89b4fa;
66
+ text-decoration: none;
67
+ font-weight: 700;
68
+ font-size: 1.2rem;
69
+ display: flex;
70
+ align-items: center;
71
+ gap: 0.5rem;
72
+ }
73
+ .back-link {
74
+ color: #a6adc8;
75
+ text-decoration: none;
76
+ font-size: 0.9rem;
77
+ padding: 0.4rem 0.8rem;
78
+ border-radius: 6px;
79
+ background: rgba(255, 255, 255, 0.05);
80
+ transition: all 0.2s;
81
+ }
82
+ .back-link:hover {
83
+ color: #ffffff;
84
+ background: rgba(255, 255, 255, 0.1);
85
+ }
86
+ .policy-title {
87
+ font-size: 2.2rem;
88
+ color: #ffffff;
89
+ margin-top: 0;
90
+ margin-bottom: 0.5rem;
91
+ }
92
+ .policy-h2 {
93
+ font-size: 1.4rem;
94
+ color: #50fa7b;
95
+ margin-top: 2rem;
96
+ margin-bottom: 0.75rem;
97
+ border-bottom: 1px solid rgba(255, 255, 255, 0.08);
98
+ padding-bottom: 0.3rem;
99
+ }
100
+ .policy-h3 {
101
+ font-size: 1.1rem;
102
+ color: #89b4fa;
103
+ margin-top: 1.5rem;
104
+ margin-bottom: 0.5rem;
105
+ }
106
+ p, li {
107
+ color: #cdd6f4;
108
+ font-size: 0.95rem;
109
+ }
110
+ ul, ol {
111
+ padding-left: 1.5rem;
112
+ margin: 0.5rem 0 1rem;
113
+ }
114
+ li {
115
+ margin-bottom: 0.35rem;
116
+ }
117
+ code {
118
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
119
+ font-size: 0.85em;
120
+ background: rgba(255, 255, 255, 0.08);
121
+ padding: 0.15rem 0.35rem;
122
+ border-radius: 4px;
123
+ color: #f5c2e7;
124
+ }
125
+ code.math {
126
+ color: #89dceb;
127
+ }
128
+ a {
129
+ color: #89b4fa;
130
+ text-decoration: underline;
131
+ }
132
+ a:hover {
133
+ color: #b4befe;
134
+ }
135
+ .divider {
136
+ border: 0;
137
+ border-top: 1px solid rgba(255, 255, 255, 0.1);
138
+ margin: 2rem 0;
139
+ }
140
+ .alert-box {
141
+ display: flex;
142
+ gap: 0.75rem;
143
+ padding: 1rem 1.25rem;
144
+ border-radius: 8px;
145
+ margin: 1.25rem 0;
146
+ align-items: flex-start;
147
+ }
148
+ .alert-warning {
149
+ background: rgba(249, 226, 175, 0.08);
150
+ border: 1px solid rgba(249, 226, 175, 0.3);
151
+ color: #f9e2af;
152
+ }
153
+ .alert-important {
154
+ background: rgba(137, 180, 250, 0.08);
155
+ border: 1px solid rgba(137, 180, 250, 0.3);
156
+ color: #89b4fa;
157
+ }
158
+ .alert-note {
159
+ background: rgba(180, 190, 254, 0.08);
160
+ border: 1px solid rgba(180, 190, 254, 0.3);
161
+ color: #b4befe;
162
+ }
163
+ .alert-icon {
164
+ font-size: 1.2rem;
165
+ line-height: 1.2;
166
+ }
167
+ .alert-body {
168
+ font-size: 0.88rem;
169
+ line-height: 1.45;
170
+ color: #cdd6f4;
171
+ }
172
+ .footer-bar {
173
+ margin-top: 3.5rem;
174
+ padding-top: 1.5rem;
175
+ border-top: 1px solid rgba(255, 255, 255, 0.1);
176
+ font-size: 0.85rem;
177
+ color: #a6adc8;
178
+ display: flex;
179
+ justify-content: space-between;
180
+ flex-wrap: wrap;
181
+ gap: 1rem;
182
+ }
183
+ </style>
184
+ </head>
185
+ <body>
186
+ <div class="page-container">
187
+ <header class="header-bar">
188
+ <a href="/" class="brand-link">
189
+ <span>◈</span>
190
+ <span>🌌 space-gib 🌌</span>
191
+ </a>
192
+ <a href="/" class="back-link">← Return to App</a>
193
+ </header>
194
+
195
+ <main>
196
+ ${bodyHtml}
197
+ </main>
198
+
199
+ <footer class="footer-bar">
200
+ <span>© ibgib contributors</span>
201
+ <span><a href="https://ibgib.space">ibgib.space</a> · <a href="https://github.com/ibgib" target="_blank" rel="noopener">GitHub</a></span>
202
+ </footer>
203
+ </div>
204
+ </body>
205
+ </html>`;
206
+
207
+ await writeFile(outputHtmlPath, fullHtml, { encoding: 'utf8' });
208
+ console.log(`${lc} complete. wrote ${outputHtmlPath}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ibgib/space-gib",
3
- "version": "0.0.19",
3
+ "version": "0.0.21",
4
4
  "type": "module",
5
5
  "description": "ibgib storage and provider service — SaaS at ibgib.space",
6
6
  "scripts": {
@@ -12,11 +12,11 @@
12
12
  "build:test": "tsc -p tsconfig.test.json"
13
13
  },
14
14
  "dependencies": {
15
- "@ibgib/core-gib": "^0.1.75",
15
+ "@ibgib/core-gib": "^0.1.77",
16
16
  "@ibgib/helper-gib": "^0.0.37",
17
17
  "@ibgib/ts-gib": "^0.5.34",
18
- "@ibgib/web-gib": "^0.0.61",
19
- "@ibgib/node-gib": "^0.0.20"
18
+ "@ibgib/web-gib": "^0.0.63",
19
+ "@ibgib/node-gib": "^0.0.22"
20
20
  },
21
21
  "engines": {
22
22
  "node": ">=20.0.0"
@@ -8,4 +8,4 @@
8
8
  /**
9
9
  * Version of space-gib, auto-updated by the build process.
10
10
  */
11
- export const AUTO_GENERATED_VERSION = '0.0.19';
11
+ export const AUTO_GENERATED_VERSION = '0.0.21';
@@ -16,4 +16,117 @@ This directory contains the browser single-page application (SPA) frontend for `
16
16
  * `api/`: REST and WebSocket API communication layers (including email send/inbound handlers).
17
17
  * `dev-tools.mts`: Utilities for rendering the local development test panel.
18
18
 
19
+ ## Mobile Device Testing (Android via ADB over Wi-Fi & USB)
20
+
21
+ To test the mobile client with full hardware Passkey/WebAuthn support (fingerprint sensors, Face Unlock) against your local Dockerized Traefik server:
22
+
23
+ ### 1. Initial Setup (via USB Cable)
24
+ 1. Ensure **Developer Options** and **USB Debugging** are enabled on your Android phone.
25
+ 2. Connect your phone to your laptop via USB.
26
+ 3. Verify connection:
27
+ ```powershell
28
+ adb devices
29
+ ```
30
+ *(Tap "Always allow from this computer" if prompted on the phone).*
31
+
32
+ ### 2. Wireless Wi-Fi Mode (Untethered)
33
+ 1. Enable TCP/IP mode on port 5555 while still plugged in:
34
+ ```powershell
35
+ adb tcpip 5555
36
+ ```
37
+ 2. Find your phone's Wi-Fi IP address on your local network (e.g. *Settings → About Phone → Status Information → IP Address*, such as `192.168.86.42`).
38
+ 3. Unplug the USB cable.
39
+ 4. Connect wirelessly:
40
+ ```powershell
41
+ adb connect 192.168.86.42:5555
42
+ ```
43
+ 5. Apply the reverse port tunnel:
44
+ ```powershell
45
+ adb reverse tcp:8443 tcp:443
46
+ ```
47
+ *(Note: Android requires non-root ports ≥ 1024, so port 8443 on the phone tunnels into port 443 on your laptop).*
48
+
49
+ ### 3. Open in Mobile Chrome
50
+ Navigate to:
51
+ ```
52
+ https://local.ibgib.space:8443
53
+ ```
54
+ *(Accept the self-signed SSL warning if prompted).*
55
+
56
+ ### 4. Reconnecting after Laptop or Phone Restart
57
+ * If only the laptop restarts (phone was not rebooted):
58
+ ```powershell
59
+ adb connect <phone-ip>:5555
60
+ adb reverse tcp:8443 tcp:443
61
+ ```
62
+ * If the phone reboots: Android turns off TCP/IP mode on port 5555 for security. Briefly plug in the USB cable, run `adb tcpip 5555`, unplug, and reconnect via Wi-Fi.
63
+
64
+ ## Passkey Testing with Chrome DevTools (Virtual Authenticators)
65
+
66
+ You can test full hardware Passkey and WebAuthn PRF functionality without needing physical biometrics or YubiKeys by using Chrome's built-in **Virtual Authenticator Environment**.
67
+
68
+ ### 1. Enable the WebAuthn DevTools Tab
69
+ 1. Open Chrome and navigate to `https://space-gib.localhost` (or `https://local.ibgib.space`).
70
+ 2. Open Chrome DevTools (`F12` or `Ctrl+Shift+I` / `Cmd+Option+I`).
71
+ 3. Click the three vertical dots (`⋮`) at top-right of DevTools $\to$ **More tools** $\to$ **WebAuthn**.
72
+ 4. Check the box **"Enable Virtual Authenticator Environment"**.
73
+
74
+ ---
75
+
76
+ ### 2. Recommended Virtual Devices to Test (Up to 3 Configurations)
77
+
78
+ You can add multiple virtual devices simultaneously to test different transport badges and multi-credential selection:
79
+
80
+ #### Device 1: Built-in Platform Biometrics (Touch ID / Windows Hello / Android)
81
+ * **Protocol**: `ctap2`
82
+ * **Transport**: `internal`
83
+ * **Checkboxes**:
84
+ * [x] `Supports resident keys`
85
+ * [x] `Supports user verification`
86
+ * [x] `Supports hmac-secret` *(enables WebAuthn PRF)*
87
+ * **Purpose**: Simulates built-in biometric hardware for zero-password account genesis and sovereign device delegation.
88
+
89
+ #### Device 2: Roaming USB Security Key (YubiKey 5Ci)
90
+ * **Protocol**: `ctap2`
91
+ * **Transport**: `usb`
92
+ * **Checkboxes**:
93
+ * [x] `Supports resident keys`
94
+ * [x] `Supports user verification`
95
+ * [x] `Supports hmac-secret` *(enables WebAuthn PRF)*
96
+ * **Purpose**: Simulates an external USB hardware key to test multi-key registration, `🔑 USB Key` transport badges, and key removal/revocation.
97
+
98
+ #### Device 3: Roaming NFC Security Key
99
+ * **Protocol**: `ctap2`
100
+ * **Transport**: `nfc`
101
+ * **Checkboxes**:
102
+ * [x] `Supports resident keys`
103
+ * [x] `Supports user verification`
104
+ * [x] `Supports hmac-secret` *(enables WebAuthn PRF)*
105
+ * **Purpose**: Tests contactless transport badges (`📶 NFC`) and dropdown credential selection in authorization dialogs.
106
+
107
+ ---
108
+
109
+ ### 3. Quick Test Flow
110
+
111
+ 1. **Test Genesis (Zero-Password Onboarding)**:
112
+ * Navigate to **New Identity**.
113
+ * Click **Tab 2: 🛡️ Passkey / Hardware**.
114
+ * Enter a username and click **🛡️ Create Sovereign Identity with Passkey**.
115
+ * The active virtual authenticator will respond automatically, creating the identity and sovereign sync delegate with 0 passwords typed!
116
+ * In DevTools WebAuthn panel, you will see the generated resident credential ID and private key appear.
117
+
118
+ 2. **Test Multi-Passkey Registration & Badges**:
119
+ * Navigate to **Identity Details** $\to$ Scroll to the **Passkeys & Hardware Authenticators** card.
120
+ * Verify your genesis passkey shows the `💻 Touch ID / Built-in` badge.
121
+ * Switch the active virtual authenticator in DevTools to **Device 2 (USB)**.
122
+ * Click **🛡️ Register New Passkey / Security Key**.
123
+ * Enter your password or authorize via DevTools $\to$ A new passkey appears with the `🔑 USB Key` badge!
124
+
125
+ 3. **Test Hybrid Dialog Authorization**:
126
+ * In **Identity Details**, click **Remove** on one of the passkeys (or click an SSO provider to unlink).
127
+ * Notice the prompt dialog displays the **`[ 🛡️ Touch ID / Security Key ]`** action button alongside the password field.
128
+ * Click the button to authorize with the virtual authenticator instantly without entering a password.
129
+
130
+ ---
131
+
19
132
  For local development commands, please refer to the [Root space-gib README](../../README.md).
@@ -94,6 +94,7 @@ export async function createAndRegisterSyncDelegate({
94
94
  parentKeystone: domainI,
95
95
  delegateKeystone,
96
96
  masterSecret,
97
+ signingPoolId: 'manage',
97
98
  metaspace,
98
99
  space,
99
100
  allowedVerbs: [KEYSTONE_VERB_SYNC]
@@ -55,7 +55,7 @@
55
55
  <button id="btn-left-panel-toggle" class="panel-toggle-btn" aria-label="Toggle Left Panel">☰</button>
56
56
  <a id="space-gib-title-link" href="/" class="brand-link">
57
57
  <span class="brand-icon">◈</span>
58
- <span class="brand-name">space<span class="brand-accent">-</span>gib</span>
58
+ <span class="brand-name">🌌 space<span class="brand-accent">-</span>gib 🌌</span>
59
59
  </a>
60
60
  <nav class="header-nav" aria-label="Main navigation">
61
61
  <a href="/docs" class="nav-link">Docs</a>
@@ -105,7 +105,8 @@
105
105
  <h2 class="dev-panel-title">Dev Tools</h2>
106
106
 
107
107
  <div class="dev-panel-select-container">
108
- <label for="dev-tools-row-select" style="color: var(--clr-warn); font-size: 0.9rem; font-weight: 500;">Select Phase:</label>
108
+ <label for="dev-tools-row-select"
109
+ style="color: var(--clr-warn); font-size: 0.9rem; font-weight: 500;">Select Phase:</label>
109
110
  <select id="dev-tools-row-select" class="dev-select">
110
111
  <option value="all">Show All</option>
111
112
  <option value="00">Row 00 (POC)</option>
@@ -293,7 +294,7 @@
293
294
  <p class="footer-text">
294
295
  <span>© ibgib contributors</span> ·
295
296
  <a href="https://ibgib.space" class="footer-link">ibgib.space</a> ·
296
- <a href="https://github.com/ibgib" class="footer-link" target="_blank" rel="noopener">GitHub</a>
297
+ <a href="/privacy" class="footer-link" target="_blank" rel="noopener">Privacy Policy</a>
297
298
  </p>
298
299
  </footer>
299
300