@qidcloud/sdk 1.2.1 → 1.2.3

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,68 +1,257 @@
1
1
  # @qidcloud/sdk
2
2
 
3
- The official JavaScript/TypeScript SDK for QidCloud. Build PQC-secured, enclave-backed applications in minutes.
3
+ The official JavaScript/TypeScript SDK for QidCloud. Build PQC-secured, enclave-backed applications with ease.
4
4
 
5
- ## 🚀 30-Minute Quick Start
5
+ ## 🚀 Installation
6
6
 
7
- ### 1. Install
8
7
  ```bash
9
8
  npm install @qidcloud/sdk
10
9
  ```
11
10
 
12
- ### 2. Initialize
11
+ ## 🛠️ Initialization
12
+
13
13
  ```typescript
14
14
  import { QidCloud } from '@qidcloud/sdk';
15
15
 
16
16
  const qid = new QidCloud({
17
17
  apiKey: 'your_api_key', // Found in QidCloud Console -> Settings
18
- tenantId: 'your_project_id'
18
+ tenantId: 'your_project_id' // Optional, for project-scoped operations
19
19
  });
20
20
  ```
21
21
 
22
22
  ---
23
23
 
24
- ## 🔑 Identity (`qid.auth`)
25
-
26
- Enforce Pure Post-Quantum Identity with zero passwords.
24
+ ## ⚠️ Prerequisite: CORS Configuration
27
25
 
28
- ### `createSession()`
29
- Initiates a new QR handshake session.
30
- - **Returns**: `Promise<QidAuthSession>`
26
+ Before using the SDK, you **must whitelist your application's domain** in the QidCloud Console.
27
+ 1. Go to **Settings > Security**.
28
+ 2. Add your app's URL (e.g., `http://localhost:5173` or `https://myapp.com`) to the **Allowed Origins** list.
29
+ 3. Without this, browser requests will be blocked by CORS policy.
31
30
 
32
31
  ---
33
32
 
34
- ## 🏗️ React Integration
33
+ ## 🛡️ Authentication Guide
35
34
 
36
- The SDK provides powerful React tools for seamless integration.
35
+ QidCloud uses a **Post-Quantum Cryptography (PQC)** handshake for authentication. Users strictly log in by scanning a QR code with their QidCloud Mobile App. **Password entry is NOT supported** in the SDK to ensure credentials never touch the client device.
37
36
 
38
- ### `useQidAuth(sdk)`
39
- The recommended way to manage auth state in React.
37
+ ### 1. Recommended: Using `QidCloudLogin` Component
38
+ The easiest way to implement secure login.
39
+ ```tsx
40
+ import { QidCloud, QidCloudLogin } from '@qidcloud/sdk';
40
41
 
42
+ const sdk = new QidCloud({
43
+ apiKey: 'your_api_key',
44
+ tenantId: 'your_project_id'
45
+ });
46
+
47
+ function App() {
48
+ return (
49
+ <QidCloudLogin
50
+ sdk={sdk}
51
+ onSuccess={(user, token) => {
52
+ console.log('Logged in:', user);
53
+ // Token is also automatically cached in localStorage by the component
54
+ }}
55
+ onError={(err) => console.error(err)}
56
+ />
57
+ );
58
+ }
59
+ ```
60
+
61
+ ### 2. Custom UI: Using `useQidAuth` Hook
62
+ For building your own UI while keeping the SDK's state management.
41
63
  ```tsx
42
64
  import { useQidAuth } from '@qidcloud/sdk';
43
65
 
44
- function MyComponent({ qid }) {
45
- const { user, token, session, login, initializing } = useQidAuth(qid);
66
+ function CustomLogin() {
67
+ const {
68
+ login, // Generates QR and starts polling
69
+ session, // Contains { qrData } to display
70
+ user, // Populated on success
71
+ logout
72
+ } = useQidAuth(sdk);
46
73
 
47
- if (user) return <p>Welcome, {user.username}</p>;
74
+ if (user) return <button onClick={logout}>Logout {user.username}</button>;
48
75
 
49
76
  return (
50
- <button onClick={login}>
51
- {initializing ? 'Connecting...' : 'Login'}
52
- </button>
77
+ <div>
78
+ <button onClick={login}>Generate QR</button>
79
+ {session && <QRCode value={session.qrData} />}
80
+ </div>
53
81
  );
54
82
  }
55
83
  ```
56
84
 
57
- ### `QidSignInButton`
58
- A plug-and-play button that handles the entire handshake UI.
85
+ ### 3. Raw Implementation (No SDK)
86
+ If you prefer to hit the endpoints directly:
87
+ 1. **Create Session**: `POST /api/auth/session` (Headers: `x-api-key`, `x-tenant-id`) -> Returns `sessionId`, `qrData`.
88
+ 2. **Display QR**: Render `qrData` as a QR code.
89
+ 3. **Listen (Socket/Poll)**: Connect to `socket.io` specific to `sessionId` OR poll status.
90
+ 4. **Exchange**: When mobile app confirms, server sends auth token.
91
+ 5. **Get Profile**: `GET /api/me` (Header: `Authorization: Bearer <token>`).
92
+
93
+ ### 📱 Mobile-to-Mobile (App-to-App) Auth
94
+ If you are building a mobile application that needs to authenticate users via the QidCloud Mobile App:
95
+
96
+ 1. **Initiate**: Call `sdk.auth.createSession()` to get a `sessionId`.
97
+ 2. **Deep Link**: Construct a deep link to the QidCloud app using the following format:
98
+ ```
99
+ qidcloud://authorize?data=<JSON_PAYLOAD>&callback=<YOUR_APP_SCHEME>
100
+ ```
101
+ - **data**: URL-encoded JSON containing `{ "sessionId": "..." }`.
102
+ - **callback**: Your app's deep link scheme (e.g., `myapp://auth-callback`).
103
+ 3. **Handle Callback**: The QidCloud app will redirect back to your callback URL with status results:
104
+ - **Success**: `myapp://auth-callback?status=accepted&userId=<APPROVER_ID>`
105
+ - **Rejection**: `myapp://auth-callback?status=rejected`
106
+ 4. **Finalize**: Your app should listen for the `authenticated` event on the socket (as shown in Step 2) to receive the final session token.
59
107
 
108
+ ---
109
+ ### 🔐 Session Management
110
+ - **Persistence**: The SDK automatically caches the token in `localStorage` under `qid_auth_token`.
111
+ - **Restoration**: On page load, `useQidAuth` checks for this token and verifies it via `/api/me`.
112
+ - **Expiry**: Tokens expire after **1 hour of inactivity**. The backend implements a sliding window, so active sessions automatically extend their validity. Handle 401 errors by calling `logout()`.
113
+
114
+ ### 🚪 Logout Handling
115
+ Always use the SDK's `logout()` method to preventing "ghost sessions".
60
116
  ```tsx
61
- import { QidSignInButton } from '@qidcloud/sdk';
117
+ const { logout } = useQidAuth(sdk);
118
+ // ...
119
+ <button onClick={logout}>Sign Out</button>
120
+ ```
121
+ **What `logout()` does:**
122
+ 1. Calls `POST /api/logout` to invalidate the session on the server.
123
+ 2. Removes the token from `localStorage`.
124
+ 3. Clears in-memory state.
125
+
126
+ ---
62
127
 
63
- <QidSignInButton
64
- sdk={qid}
65
- onSuccess={(user, token) => console.log(user)}
66
- onError={(err) => alert(err)}
67
- />
128
+ ## 🗄️ Secure Vault (`qid.vault`)
129
+
130
+ ### `upload(file, name, metadata?, userToken?)`
131
+ Encrypt and upload a file to the secure enclave.
132
+ - **Returns**: `Promise<QidUploadResponse>`
133
+ ```typescript
134
+ await qid.vault.upload(fileBlob, 'secret.pdf', { tag: 'confidential' }, userToken);
135
+ ```
136
+
137
+ ### `list(userToken?)`
138
+ List all encrypted files.
139
+ - **Returns**: `Promise<QidFile[]>`
140
+ ```typescript
141
+ const files = await qid.vault.list(userToken);
142
+ ```
143
+
144
+ ### `download(fileId, userToken?)`
145
+ Download a file as an ArrayBuffer.
146
+ ```typescript
147
+ const buffer = await qid.vault.download('file_123', userToken);
148
+ ```
149
+
150
+ ### `delete(fileId, userToken?)`
151
+ Soft delete a file (move to recycle bin).
152
+ ```typescript
153
+ await qid.vault.delete('file_123', userToken);
68
154
  ```
155
+
156
+ ---
157
+
158
+ ## ⚡ Edge Computing (`qid.edge`)
159
+
160
+ ### `invoke(name, params?, userToken?)`
161
+ Invoke a serverless edge function.
162
+ - **Returns**: `Promise<QidEdgeResponse>`
163
+ ```typescript
164
+ const result = await qid.edge.invoke('secure-calc', { input: 42 }, userToken);
165
+ ```
166
+
167
+ ### `list()`
168
+ List all provisioned functions.
169
+ ```typescript
170
+ const functions = await qid.edge.list();
171
+ ```
172
+
173
+ ### `getLogs(name, userToken?)`
174
+ Get logs for a specific function.
175
+ ```typescript
176
+ const logs = await qid.edge.getLogs('my-function', userToken);
177
+ ```
178
+
179
+ ### `deploy(data, userToken?)`
180
+ Deploy or update a function.
181
+ ```typescript
182
+ await qid.edge.deploy({
183
+ name: 'new-func',
184
+ code: '...',
185
+ runtime: 'node18'
186
+ }, userToken);
187
+ ```
188
+
189
+ ---
190
+
191
+ ## 📊 Observability (`qid.logs`)
192
+
193
+ ### `write(message, source?, level?, meta?)`
194
+ Ingest custom telemetry into the enclave.
195
+ ```typescript
196
+ await qid.logs.write('User action detected', 'frontend', 'info', { userId: '123' });
197
+ ```
198
+
199
+ ### `fetch(query?)`
200
+ Retrieve project logs.
201
+ ```typescript
202
+ const logs = await qid.logs.fetch({ limit: 50, level: 'error' });
203
+ ```
204
+
205
+ ---
206
+
207
+
208
+ ---
209
+
210
+ ## ✅ Production Readiness Checklist
211
+
212
+ To ensure a secure and robust integration, verify the following before going live:
213
+
214
+ - [ ] **HTTPS Only**: Ensure your application is served over HTTPS. The SDK's cryptographic features (and many browser security APIs) require a secure context.
215
+ - [ ] **Environment Variables**: Store your `apiKey` and `tenantId` in environment variables (e.g., `VITE_QID_API_KEY`) ensuring they are not hardcoded in version control.
216
+ - [ ] **Error Boundaries**: Wrap the `QidCloudLogin` component in a React Error Boundary to gracefully handle any unexpected runtime failures.
217
+ - [ ] **Strict Mode**: If using React Strict Mode, ensure your `useEffect` logic handles double-invocation (The SDK's hooks are already optimized for this).
218
+ - [ ] **CORS**: Double-check that all your production domains (including `www` and non-`www`) are whitelisted in the QidCloud Console.
219
+
220
+ ## ⚛️ React Helpers
221
+
222
+ ### `useQidAuth(sdk)`
223
+ Hook for managing authentication state.
224
+ ```tsx
225
+ const { user, login, logout } = useQidAuth(qid);
226
+ ```
227
+
228
+ ### `QidSignInButton`
229
+ Pre-built component for PQC login.
230
+ ```tsx
231
+ <QidSignInButton sdk={qid} onSuccess={(user) => console.log(user)} />
232
+ ```
233
+
234
+ ---
235
+
236
+ ## ❓ Troubleshooting
237
+
238
+ ### "Invalid hook call" after linking the SDK locally
239
+ If you are developing the SDK locally and linking it to your project (via `npm link` or `npm install ../sdk-path`), you might encounter an "Invalid hook call" error. This is usually caused by **Duplicate React** (the app and the SDK are using different React instances).
240
+
241
+ **Solution for Vite projects:**
242
+ Add `resolve.dedupe` to your `vite.config.ts` to force both your app and the SDK to share the same React instance.
243
+
244
+ ```typescript
245
+ // vite.config.ts
246
+ import { defineConfig } from 'vite'
247
+
248
+ export default defineConfig({
249
+ // ... rest of config
250
+ resolve: {
251
+ dedupe: ['react', 'react-dom']
252
+ }
253
+ })
254
+ ```
255
+
256
+ **Manual Check:**
257
+ Ensure that the `@qidcloud/sdk` folder does NOT have a `node_modules/react` directory. If it does, delete it manually so it defers to your project's React.
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import { QidCloud } from '../index';
3
+ import { QidUser } from '../types';
4
+ interface QidCloudLoginProps {
5
+ sdk: QidCloud;
6
+ onSuccess: (user: QidUser, token: string) => void;
7
+ onError?: (error: string) => void;
8
+ className?: string;
9
+ }
10
+ /**
11
+ * A comprehensive login component for QidCloud.
12
+ * STRICT SECURITY: ONLY supports QR Scanning (Mobile App) for Post-Quantum security.
13
+ * Conventional login is not available in the SDK to prevent password transmission in third-party apps.
14
+ */
15
+ export declare const QidCloudLogin: React.FC<QidCloudLoginProps>;
16
+ export {};
@@ -7,9 +7,12 @@ export interface UseQidAuthReturn {
7
7
  error: string | null;
8
8
  session: QidAuthSession | null;
9
9
  initializing: boolean;
10
+ isExpired: boolean;
11
+ timeLeft: number;
10
12
  login: () => Promise<void>;
11
13
  logout: () => void;
12
14
  cancel: () => void;
15
+ setAuthenticated: (user: QidUser, token: string) => void;
13
16
  }
14
17
  /**
15
18
  * A React hook for managing QidCloud authentication lifecycle.
package/dist/index.d.ts CHANGED
@@ -22,4 +22,5 @@ export declare class QidCloud {
22
22
  export default QidCloud;
23
23
  export * from './types';
24
24
  export { QidSignInButton } from './components/QidSignInButton';
25
+ export { QidCloudLogin } from './components/QidCloudLogin';
25
26
  export { useQidAuth } from './hooks/useQidAuth';