@coasys/ad4m-connect 0.10.0 → 0.10.1-multi-user-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/README.md CHANGED
@@ -1,60 +1,110 @@
1
- # AD4M connection library and wizard for apps
1
+ # AD4M Connection Library and Authentication Wizard
2
2
 
3
- This package makes it easy for AD4M apps to connect to a local or remote AD4M executor by handling all the complex things like finding the local executor port, requesting and storing a capability token, creating and recreating an Ad4mClient.
3
+ A powerful library that simplifies connecting applications to AD4M executors by handling:
4
+ - Executor discovery and connection
5
+ - Capability-based authentication
6
+ - Token management and storage
7
+ - Connection state management
4
8
 
5
9
  <div style="text-align: center">
6
- <img src="screenshots/Screenshot_executor_url.png" width="400"></img>
10
+ <img src="/docs/public/images/connect1.jpg" width="400" alt="AD4M Connect Initial Screen"></img>
7
11
  </div>
8
12
 
13
+ ## Overview
14
+
15
+ AD4M uses a capability-based security model to protect user data and control access to agent functionality. Every application that wants to interact with an AD4M executor needs to request specific capabilities, which are then granted (or denied) by the user.
16
+
17
+ ### What are Capabilities?
18
+
19
+ Capabilities in AD4M are like permission tokens that:
20
+ - Define what data an application can access (which perspectives)
21
+ - Specify what operations an application can perform
22
+ - Are scoped to specific domains and functions
23
+ - Can be revoked by the user at any time
24
+
25
+ A capability token might grant permissions like:
26
+ - Read access to specific perspectives
27
+ - Write access to create or modify links
28
+ - Ability to create new perspectives
29
+ - Permission to manage agent relationships
30
+ - Access to specific language functions
31
+
9
32
  ## Installation
10
33
 
11
- `npm install -s @coasys/ad4m-connect`
34
+ ```bash
35
+ npm install -s @coasys/ad4m-connect
36
+ ```
12
37
 
13
- ## Properties
38
+ ## Authentication Flow
14
39
 
15
- - `appName(required)`: Name of the application using ad4m-connect.
16
- - `appDesc(required)`: Description of the application using ad4m-connect.
17
- - `appDomain(required)`: Domain of the application using ad4m-connect.
18
- - `capabilities(required)`: Capabilities requested by the application.
19
- - `appIconPath`: Icon for the app using ad4m-connect.
20
- - `port`: Port that AD4M is running on.
21
- - `token`: JWT token if you have one.
22
- - `url`: The url that we should connect to.
40
+ When an application wants to connect to an AD4M executor, it goes through a secure authentication handshake:
23
41
 
24
- ## Events
42
+ 1. The application requests access with specific capabilities
43
+ 2. The AD4M executor generates a random verification code
44
+ 3. The user must confirm the request and enter the code
45
+ 4. Upon successful verification, a capability token is issued
46
+
47
+ ### Visual Flow
48
+
49
+ 1. Initial Connection Screen:
50
+ ![Initial Connection](/docs/public/images/connect1.jpg)
51
+
52
+ 2. Executor Found:
53
+ ![Executor Found](/docs/public/images/connect2.jpg)
25
54
 
26
- - `authstatechange`: `authenticated` | `unauthenticated` | `locked`
27
- - `connectionstatechange`: `connecting` | `connected` | `not_connected` | `disconnected` | `error`;
28
- - `configstatechange`: `token` | `url` | `port`
55
+ 3. Authorization Request:
56
+ ![Authorization Request](/docs/public/images/authorize1.jpg)
29
57
 
30
- ## In the Browser
58
+ 4. Verification Code:
59
+ ![Verification Code](/docs/public/images/authorize2.jpg)
60
+
61
+ ## Usage
62
+
63
+ ### In the Browser
31
64
 
32
65
  ```js
33
66
  import Ad4mConnectUI from "@coasys/ad4m-connect";
34
67
 
35
68
  const ui = Ad4mConnect({
36
- appName: "Example",
37
- appDesc: "This is a sample app.",
38
- appDomain: "ad4m.dev",
39
- appIconPath: "https://i.ibb.co/GnqjPJP/icon.png",
40
- capabilities: [{ with: { domain: "*", pointers: ["*"] }, can: ["*"] }],
69
+ // Required parameters
70
+ appName: "My AD4M App",
71
+ appDesc: "A description of what your app does",
72
+ appDomain: "myapp.com",
73
+ capabilities: [{
74
+ with: { domain: "*", pointers: ["*"] },
75
+ can: ["*"]
76
+ }],
77
+
78
+ // Optional parameters
79
+ appIconPath: "https://myapp.com/icon.png",
80
+ port: 12345, // Custom port
81
+ token: "existing-token", // Existing JWT token
82
+ url: "custom-executor-url" // Custom executor URL
41
83
  });
42
84
 
85
+ // Listen for authentication state changes
43
86
  ui.addEventListener("authstatechange", (e) => {
44
- if (e.detail === "authenticated") {
45
- // We are authenticated
87
+ switch(e.detail) {
88
+ case "authenticated":
89
+ console.log("Successfully authenticated");
90
+ break;
91
+ case "unauthenticated":
92
+ console.log("Not authenticated");
93
+ break;
94
+ case "locked":
95
+ console.log("Agent is locked");
96
+ break;
46
97
  }
47
98
  });
48
99
 
49
- // Open popup and save the client when we are done
100
+ // Connect and get AD4M client
50
101
  ui.connect().then((client) => {
51
- // Save the client
102
+ // Client is now ready to use
103
+ console.log("Connected with capabilities");
52
104
  });
53
105
  ```
54
106
 
55
- ## Usage (from Node / Electron)
56
-
57
- Call ad4mConnect with parameters of your app:
107
+ ### In Node.js / Electron
58
108
 
59
109
  ```js
60
110
  const { ad4mConnect } = require("@coasys/ad4m-connect/electron");
@@ -91,9 +141,55 @@ ad4mConnect({
91
141
  });
92
142
  ```
93
143
 
94
- # Extra steps to be used in capacitor:
144
+ ### Capability Specification
145
+
146
+ When requesting capabilities, specify:
147
+
148
+ ```js
149
+ {
150
+ with: {
151
+ domain: string | "*", // Which perspective/domain
152
+ pointers: string[] | "*" // Which parts of the domain
153
+ },
154
+ can: string[] | "*" // Which operations are allowed
155
+ }
156
+ ```
157
+
158
+ Examples:
159
+ ```js
160
+ // Full access (development only)
161
+ { with: { domain: "*", pointers: ["*"] }, can: ["*"] }
162
+
163
+ // Read-only access to a perspective
164
+ { with: { domain: "perspective-uuid", pointers: ["*"] }, can: ["read"] }
165
+
166
+ // Specific operations on a domain
167
+ { with: { domain: "friends", pointers: ["*"] }, can: ["read", "add", "remove"] }
168
+ ```
169
+
170
+ ## Events
171
+
172
+ The library emits various events to help track connection state:
173
+
174
+ - `authstatechange`:
175
+ - `authenticated`: Successfully connected with capabilities
176
+ - `unauthenticated`: No valid authentication
177
+ - `locked`: Agent is locked
178
+
179
+ - `connectionstatechange`:
180
+ - `connecting`: Attempting to connect
181
+ - `connected`: Successfully connected
182
+ - `not_connected`: No connection
183
+ - `disconnected`: Lost connection
184
+ - `error`: Connection error
185
+
186
+ - `configstatechange`: Configuration changes for `token`, `url`, or `port`
187
+
188
+ ## Mobile Integration
95
189
 
96
- - On Android
190
+ ### Android Setup
191
+
192
+ Add to `android/app/src/main/AndroidManifest.xml`:
97
193
  ```diff
98
194
  <?xml version="1.0" encoding="utf-8"?>
99
195
  <manifest
@@ -112,7 +208,9 @@ ad4mConnect({
112
208
  </manifest>
113
209
  ```
114
210
 
115
- - On IOs
211
+ ### iOS Setup
212
+
213
+ Add to `Info.plist`:
116
214
  ```diff
117
215
  <dict>
118
216
  + <key>NSCameraUsageDescription</key>
@@ -120,4 +218,35 @@ ad4mConnect({
120
218
  </dict>
121
219
  ```
122
220
 
123
- - Then run `npx cap sync` & `npx cap build`
221
+ After changes, run:
222
+ ```bash
223
+ npx cap sync
224
+ npx cap build
225
+ ```
226
+
227
+ ## Best Practices
228
+
229
+ 1. **Request Minimal Capabilities**
230
+ - Only request permissions your app actually needs
231
+ - Use specific domains and operations instead of wildcards
232
+ - Consider read-only access when possible
233
+
234
+ 2. **Handle Authentication States**
235
+ - Check if capabilities are still valid
236
+ - Implement reconnection logic
237
+ - Handle capability revocation gracefully
238
+
239
+ 3. **Secure Storage**
240
+ - Store capability tokens securely
241
+ - Never expose admin credentials
242
+ - Implement token refresh mechanisms
243
+
244
+ 4. **User Experience**
245
+ - Clearly explain why your app needs certain capabilities
246
+ - Provide feedback during the authentication process
247
+ - Handle errors gracefully
248
+
249
+ ## More Information
250
+
251
+ For more details about AD4M authentication and capabilities:
252
+ - [AD4M Documentation](https://docs.ad4m.dev/auth)
@@ -0,0 +1,13 @@
1
+ type ConnectionOverviewProps = {
2
+ localDetected: boolean;
3
+ multiUserConfigured: boolean;
4
+ backendUrl?: string;
5
+ configuredUrl?: string;
6
+ isMobile: boolean;
7
+ onConnectLocal: () => void;
8
+ onConnectRemote: () => void;
9
+ onScanQR: () => void;
10
+ onDownloadAd4m: () => void;
11
+ };
12
+ export default function ConnectionOverview({ localDetected, multiUserConfigured, backendUrl, configuredUrl, isMobile, onConnectLocal, onConnectRemote, onScanQR, onDownloadAd4m, }: ConnectionOverviewProps): import("lit").TemplateResult<1>;
13
+ export {};
@@ -0,0 +1,15 @@
1
+ type MultiUserAuthProps = {
2
+ email: string;
3
+ password: string;
4
+ error: string | null;
5
+ isLoading: boolean;
6
+ backendUrl?: string;
7
+ changeEmail: (email: string) => void;
8
+ changePassword: (password: string) => void;
9
+ onLogin: () => void;
10
+ onSignup: () => void;
11
+ activeTab: "login" | "signup";
12
+ setActiveTab: (tab: "login" | "signup") => void;
13
+ };
14
+ export default function MultiUserAuth({ email, password, error, isLoading, backendUrl, changeEmail, changePassword, onLogin, onSignup, activeTab, setActiveTab, }: MultiUserAuthProps): import("lit").TemplateResult<1>;
15
+ export {};
@@ -0,0 +1,13 @@
1
+ type RemoteConnectionProps = {
2
+ initialUrl?: string;
3
+ detecting: boolean;
4
+ multiUserDetected: boolean | null;
5
+ error: string | null;
6
+ onBack: () => void;
7
+ onUrlChange: (url: string) => void;
8
+ onConnect: () => void;
9
+ onMultiUserAuth: () => void;
10
+ onRequestCapability: () => void;
11
+ };
12
+ export default function RemoteConnection({ initialUrl, detecting, multiUserDetected, error, onBack, onUrlChange, onConnect, onMultiUserAuth, onRequestCapability, }: RemoteConnectionProps): import("lit").TemplateResult<1>;
13
+ export {};
package/dist/core.d.ts CHANGED
@@ -14,11 +14,15 @@ export type Ad4mConnectOptions = {
14
14
  url?: string;
15
15
  hosting?: boolean;
16
16
  mobile?: boolean;
17
+ multiUser?: boolean;
18
+ backendUrl?: string;
19
+ userEmail?: string;
20
+ userPassword?: string;
17
21
  };
18
22
  export type AuthStates = "authenticated" | "locked" | "unauthenticated";
19
23
  export type Event = "authstatechange" | "connectionstatechange" | "configstatechange";
20
24
  export type ConfigStates = "port" | "url" | "token";
21
- export type ConnectionStates = "connecting" | "connected" | "error" | "port_not_found" | "not_connected" | "disconnected";
25
+ export type ConnectionStates = "connecting" | "connected" | "error" | "port_not_found" | "not_connected" | "disconnected" | "checking_local";
22
26
  export default class Ad4mConnect {
23
27
  activeSocket: WebSocket;
24
28
  requestedRestart: boolean;
@@ -38,8 +42,9 @@ export default class Ad4mConnect {
38
42
  appIconPath: string;
39
43
  appUrl?: string;
40
44
  isHosting: boolean;
45
+ options: Ad4mConnectOptions;
41
46
  listeners: Record<Event, Function[]>;
42
- constructor({ appName, appDesc, appIconPath, appUrl, appDomain, capabilities, port, token, url, hosting }: Ad4mConnectOptions);
47
+ constructor(options: Ad4mConnectOptions);
43
48
  private notifyConfigChange;
44
49
  private notifyConnectionChange;
45
50
  private notifyAuthChange;
@@ -47,7 +52,9 @@ export default class Ad4mConnect {
47
52
  setUrl(url: string): void;
48
53
  setToken(token: string): void;
49
54
  on(event: Event, cb: Function): void;
55
+ buildTempClient(url: string): Ad4mClient;
50
56
  connect(url?: string): Promise<Ad4mClient>;
57
+ connectMultiUser(): Promise<Ad4mClient>;
51
58
  loginToHosting(email: string, password: string): Promise<void>;
52
59
  checkEmail(email: string): Promise<boolean>;
53
60
  connectToPort(port?: number): Promise<Ad4mClient>;