@proveanything/smartlinks 1.15.16 → 1.15.18
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 +8 -0
- package/dist/api/appObjects.d.ts +6 -0
- package/dist/api/appObjects.js +10 -0
- package/dist/api/navigation.js +3 -2
- package/dist/api/proof.d.ts +19 -1
- package/dist/api/proof.js +44 -0
- package/dist/docs/API_SUMMARY.md +90 -1
- package/dist/docs/app-objects.md +65 -0
- package/dist/docs/assets.md +81 -0
- package/dist/docs/proof-share-grants.md +232 -0
- package/dist/http.d.ts +19 -0
- package/dist/http.js +49 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/openapi.yaml +231 -0
- package/dist/types/appObjects.d.ts +14 -0
- package/dist/types/navigation.d.ts +5 -0
- package/dist/types/proof.d.ts +55 -0
- package/docs/API_SUMMARY.md +90 -1
- package/docs/app-objects.md +65 -0
- package/docs/assets.md +81 -0
- package/docs/proof-share-grants.md +232 -0
- package/openapi.yaml +231 -0
- package/package.json +1 -1
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# Proof Share Grants
|
|
2
|
+
|
|
3
|
+
Delegated, scoped, **revocable** bearer access to a single proof — the middle tier
|
|
4
|
+
between "public" (everyone) and "owner" (only the signed-in owner).
|
|
5
|
+
|
|
6
|
+
A grant lets an owner hand out a link that lets specific recipients **see or do
|
|
7
|
+
specific things on one proof for a limited time**, without those recipients needing
|
|
8
|
+
a SmartLinks account or a proof claim. Typical uses: sharing a private photo album,
|
|
9
|
+
letting guests comment on it, or publishing a verifiable "I own this" assertion.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Concepts
|
|
14
|
+
|
|
15
|
+
A **grant** is a row issued by the proof owner (or a collection admin) and redeemed
|
|
16
|
+
by a bearer holding an opaque token. Every data request that touches the proof
|
|
17
|
+
re-checks the grant **server-side** against the database, so revocation is immediate.
|
|
18
|
+
|
|
19
|
+
### Scopes — what a grant authorises
|
|
20
|
+
|
|
21
|
+
| Scope | Grants the bearer… |
|
|
22
|
+
|-------|--------------------|
|
|
23
|
+
| `read` | read owner-tier data on the proof (attestations, threads, records, cases) |
|
|
24
|
+
| `comment` | create threads/replies on the proof (guest comments) |
|
|
25
|
+
| `admin` | read owner-tier data (reserved for elevated share cases; never exposes the platform admin zone) |
|
|
26
|
+
| `verify_owner` | redeem a shareable ownership **assertion** (not the account) |
|
|
27
|
+
|
|
28
|
+
A grant can carry several scopes, e.g. `['read', 'comment']` for a shareable,
|
|
29
|
+
commentable album.
|
|
30
|
+
|
|
31
|
+
### Security & lifecycle
|
|
32
|
+
|
|
33
|
+
- The token is opaque, unguessable, and returned to the issuer **exactly once** (on `createGrant`). It is never returned by `listGrants`.
|
|
34
|
+
- **Revocation is immediate** — the grant is re-checked on every request, so `revokeGrant` invalidates a token across all clients at once.
|
|
35
|
+
- **Auto-invalidation on transfer** — every grant is voided the moment the proof's `ownerId` changes (e.g. a resale/re-claim), so a stale "I own this" link cannot keep resolving.
|
|
36
|
+
- A grant is scoped to **one proof**; it can never widen access to other proofs or collection-level data.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Owner flow — create, list, revoke
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { proof } from '@proveanything/smartlinks'
|
|
44
|
+
|
|
45
|
+
// Create a read+comment grant that expires in 7 days.
|
|
46
|
+
const grant = await proof.createGrant(collectionId, productId, proofId, {
|
|
47
|
+
scope: ['read', 'comment'],
|
|
48
|
+
audience: { kind: 'public_link' },
|
|
49
|
+
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
// `grant.token` is available ONLY here — embed it in your share link now.
|
|
53
|
+
const shareUrl = `https://app.example.com/album?proofId=${proofId}&shareToken=${grant.token}`
|
|
54
|
+
|
|
55
|
+
// List active + past grants (tokens are never included).
|
|
56
|
+
const grants = await proof.listGrants(collectionId, productId, proofId)
|
|
57
|
+
|
|
58
|
+
// Stop sharing — takes effect on the very next request from any client.
|
|
59
|
+
await proof.revokeGrant(collectionId, productId, proofId, grant.grantId)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`createGrant` / `listGrants` / `revokeGrant` require the caller to be the **proof
|
|
63
|
+
owner** (or a collection admin) — i.e. a signed-in user whose `bearerToken` is set.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Recipient flow — redeem, then carry the token
|
|
68
|
+
|
|
69
|
+
A recipient opens the share link, redeems the token once, then sets it as the
|
|
70
|
+
active grant token. From then on **every** SDK request carries the token
|
|
71
|
+
(`X-Grant-Token`), so all proof reads/writes are evaluated against the grant.
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import { proof, setGrantToken } from '@proveanything/smartlinks'
|
|
75
|
+
|
|
76
|
+
const shareToken = new URLSearchParams(location.search).get('shareToken')!
|
|
77
|
+
|
|
78
|
+
// Redeem once (anonymous or signed-in). Records the redemption; optionally names the guest.
|
|
79
|
+
await proof.redeemGrant(collectionId, productId, proofId, shareToken, {
|
|
80
|
+
guestName: 'Sam', // stamped on guest activity when not signed in
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
// Attach the token to every subsequent request.
|
|
84
|
+
setGrantToken(shareToken)
|
|
85
|
+
|
|
86
|
+
// Now grant-tier reads succeed — e.g. owner-visibility memories on the proof:
|
|
87
|
+
const { attestations } = await attestation.publicList(collectionId, {
|
|
88
|
+
subjectType: 'proof', subjectId: proofId,
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
// Clear it when leaving the shared view:
|
|
92
|
+
setGrantToken(undefined)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
> **Persisting across reloads.** `setGrantToken` holds the token in memory. To keep a
|
|
96
|
+
> shared session across reloads, persist `shareToken` yourself (e.g. in `localStorage`)
|
|
97
|
+
> and call `setGrantToken` again on load.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Guest commenting
|
|
102
|
+
|
|
103
|
+
With a `comment` scope grant, a bearer can post comments even when they are not
|
|
104
|
+
signed in. The app must enable the **grant branch** of the thread create policy
|
|
105
|
+
(see [App config](#app-config)); comments are then created at `visibility: 'owner'`
|
|
106
|
+
(private to the proof) and stamped `authorType: 'guest'`.
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
import { app } from '@proveanything/smartlinks'
|
|
110
|
+
// setGrantToken(shareToken) has already been called.
|
|
111
|
+
|
|
112
|
+
// One atomic call — no separate create-then-reply round trip.
|
|
113
|
+
await app.threads.create(collectionId, 'photo-memory', {
|
|
114
|
+
parentType: 'memory',
|
|
115
|
+
parentId: memoryId, // text — SmartLinks short ids are fine (not just UUIDs)
|
|
116
|
+
proofId, // anchor to the proof so grant readers see it
|
|
117
|
+
firstReply: { text: 'Lovely photo', authorName: 'Sam' },
|
|
118
|
+
})
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Other grant holders (and the owner) see these comments because a `read` grant reveals
|
|
122
|
+
`owner`-visibility threads for the proof. See
|
|
123
|
+
[App Objects → Threads](app-objects.md#threads) for the full threads API.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Proof of ownership — `verify_owner`
|
|
128
|
+
|
|
129
|
+
Ownership itself is **not** a grant — it is `proof.ownerId`, established via the
|
|
130
|
+
existing [claim flow](proof-claiming-methods.md). A `verify_owner` grant only
|
|
131
|
+
publishes a shareable, verifiable **assertion** derived from that ownership, without
|
|
132
|
+
handing over the account:
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
const grant = await proof.createGrant(collectionId, productId, proofId, {
|
|
136
|
+
scope: ['verify_owner'],
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
// The recipient redeems it and gets the assertion — never the account:
|
|
140
|
+
const result = await proof.redeemGrant(collectionId, productId, proofId, grant.token)
|
|
141
|
+
// { proofId, assertsOwnership: true, ownerDisplayName?, issuedAt, expiresAt }
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Because grants auto-invalidate on transfer, a resale cannot leave a stale
|
|
145
|
+
"I own this" link in circulation.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## What a grant gates
|
|
150
|
+
|
|
151
|
+
When a valid grant token is present, these public reads elevate to owner-tier for the
|
|
152
|
+
granted proof (and only that proof):
|
|
153
|
+
|
|
154
|
+
- **Attestations** — `attestation.publicList({ subjectType: 'proof', subjectId })`
|
|
155
|
+
- **Threads / Records / Cases** — `app.threads.list`, `app.records.*`, `app.cases.list`, and the single-item GETs, filtered to the granted proof
|
|
156
|
+
- **Thread creation / replies** — with a `comment` scope grant (see below)
|
|
157
|
+
|
|
158
|
+
The token never exposes the platform `admin` zone, and only reveals `owner`-visibility
|
|
159
|
+
rows for the granted `proofId`.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## App config
|
|
164
|
+
|
|
165
|
+
Grant-based commenting is opt-in per app, configured on the app's Firestore config
|
|
166
|
+
at `sites/{collectionId}/apps/{appId}` — a `grant` branch alongside
|
|
167
|
+
`anonymous` / `authenticated`:
|
|
168
|
+
|
|
169
|
+
```jsonc
|
|
170
|
+
{
|
|
171
|
+
"publicCreate": {
|
|
172
|
+
"threads": {
|
|
173
|
+
"grant": {
|
|
174
|
+
"allow": true,
|
|
175
|
+
"requireScope": "comment",
|
|
176
|
+
"enforce": { "visibility": "owner", "status": "open" }
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
This enables grant-scoped commenting **without** opening up anonymous creation. The
|
|
184
|
+
`enforce.visibility: "owner"` keeps comments private to the proof (visible to the
|
|
185
|
+
owner and other grant holders, not the wider public).
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## API reference
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
namespace proof {
|
|
193
|
+
createGrant(collectionId, productId, proofId, options: CreateGrantOptions): Promise<ProofGrant>
|
|
194
|
+
listGrants(collectionId, productId, proofId): Promise<ProofGrant[]>
|
|
195
|
+
revokeGrant(collectionId, productId, proofId, grantId): Promise<void>
|
|
196
|
+
redeemGrant(collectionId, productId, proofId, token, options?: RedeemGrantOptions): Promise<RedeemGrantResult>
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Attach / clear the active grant token (sent as X-Grant-Token on every request).
|
|
200
|
+
function setGrantToken(token: string | undefined): void
|
|
201
|
+
function getGrantToken(): string | undefined
|
|
202
|
+
|
|
203
|
+
type GrantScope = 'read' | 'comment' | 'admin' | 'verify_owner'
|
|
204
|
+
|
|
205
|
+
interface CreateGrantOptions {
|
|
206
|
+
scope: GrantScope[] // at least one
|
|
207
|
+
audience?: { kind: 'public_link' } | { kind: 'named'; email?: string; userId?: string }
|
|
208
|
+
expiresAt?: Date | string
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
interface RedeemGrantOptions { guestName?: string }
|
|
212
|
+
|
|
213
|
+
type RedeemGrantResult =
|
|
214
|
+
| { scope: GrantScope[]; redeemedAt: string }
|
|
215
|
+
| { proofId: string; assertsOwnership: true; ownerDisplayName?: string; issuedAt?: string; expiresAt?: string }
|
|
216
|
+
|
|
217
|
+
interface ProofGrant {
|
|
218
|
+
grantId: string
|
|
219
|
+
proofId: string
|
|
220
|
+
productId?: string | null
|
|
221
|
+
scope: GrantScope[]
|
|
222
|
+
audience: { kind: 'public_link' | 'named'; email?: string; userId?: string }
|
|
223
|
+
createdBy: string
|
|
224
|
+
expiresAt?: string | null
|
|
225
|
+
revokedAt?: string | null
|
|
226
|
+
redeemedBy?: { userId?: string; guestName?: string; redeemedAt: string }
|
|
227
|
+
redeemCount: number
|
|
228
|
+
createdAt: string
|
|
229
|
+
updatedAt: string
|
|
230
|
+
token?: string // present ONLY on the createGrant response
|
|
231
|
+
}
|
|
232
|
+
```
|
package/dist/http.d.ts
CHANGED
|
@@ -49,6 +49,25 @@ export declare function setExtraHeaders(headers: Record<string, string>): void;
|
|
|
49
49
|
* login or logout event.
|
|
50
50
|
*/
|
|
51
51
|
export declare function setBearerToken(token: string | undefined): void;
|
|
52
|
+
/**
|
|
53
|
+
* Set (or clear) the per-proof share-grant token. When set, it is attached as the
|
|
54
|
+
* `X-Grant-Token` header on every request, so a recipient who has opened a shared
|
|
55
|
+
* link can read/comment on the granted proof's data. Pass `undefined` to clear it.
|
|
56
|
+
*
|
|
57
|
+
* The server re-checks the grant against the database on every request, so calling
|
|
58
|
+
* `revokeGrant` invalidates an in-flight token immediately. Clears the GET cache on
|
|
59
|
+
* change so grant-tier responses are not served after the token changes.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* // On opening ?proofId=…&shareToken=abc
|
|
64
|
+
* setGrantToken(shareToken)
|
|
65
|
+
* const { attestations } = await proof.get(...) // now sees owner-tier memories
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export declare function setGrantToken(token: string | undefined): void;
|
|
69
|
+
/** Returns the currently-set share-grant token, or `undefined`. */
|
|
70
|
+
export declare function getGrantToken(): string | undefined;
|
|
52
71
|
/**
|
|
53
72
|
* Returns the bearer token currently held by the SDK, or `undefined` if none is set.
|
|
54
73
|
* In proxy mode, credentials are held by the parent frame, not the local SDK,
|
package/dist/http.js
CHANGED
|
@@ -39,6 +39,12 @@ let extraHeadersGlobal = {};
|
|
|
39
39
|
* issue refresh tokens and short-lived access tokens. Undefined → web behaviour.
|
|
40
40
|
*/
|
|
41
41
|
let clientPlatform = undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Per-proof share-grant bearer token. When set (via setGrantToken), it is attached
|
|
44
|
+
* as `X-Grant-Token` on every request so the server can evaluate the grant on any
|
|
45
|
+
* data call that touches the granted proof (attestations, threads, app data).
|
|
46
|
+
*/
|
|
47
|
+
let grantToken = undefined;
|
|
42
48
|
/** Whether initializeApi has been successfully called at least once. */
|
|
43
49
|
let initialized = false;
|
|
44
50
|
/** Safely returns the current browser hostname, or an empty string in non-browser / Node environments. */
|
|
@@ -466,6 +472,34 @@ export function setBearerToken(token) {
|
|
|
466
472
|
if (cachePersistence !== 'none')
|
|
467
473
|
idbClear().catch(() => { });
|
|
468
474
|
}
|
|
475
|
+
/**
|
|
476
|
+
* Set (or clear) the per-proof share-grant token. When set, it is attached as the
|
|
477
|
+
* `X-Grant-Token` header on every request, so a recipient who has opened a shared
|
|
478
|
+
* link can read/comment on the granted proof's data. Pass `undefined` to clear it.
|
|
479
|
+
*
|
|
480
|
+
* The server re-checks the grant against the database on every request, so calling
|
|
481
|
+
* `revokeGrant` invalidates an in-flight token immediately. Clears the GET cache on
|
|
482
|
+
* change so grant-tier responses are not served after the token changes.
|
|
483
|
+
*
|
|
484
|
+
* @example
|
|
485
|
+
* ```ts
|
|
486
|
+
* // On opening ?proofId=…&shareToken=abc
|
|
487
|
+
* setGrantToken(shareToken)
|
|
488
|
+
* const { attestations } = await proof.get(...) // now sees owner-tier memories
|
|
489
|
+
* ```
|
|
490
|
+
*/
|
|
491
|
+
export function setGrantToken(token) {
|
|
492
|
+
if (token === grantToken)
|
|
493
|
+
return;
|
|
494
|
+
grantToken = token;
|
|
495
|
+
httpCache.clear();
|
|
496
|
+
if (cachePersistence !== 'none')
|
|
497
|
+
idbClear().catch(() => { });
|
|
498
|
+
}
|
|
499
|
+
/** Returns the currently-set share-grant token, or `undefined`. */
|
|
500
|
+
export function getGrantToken() {
|
|
501
|
+
return grantToken;
|
|
502
|
+
}
|
|
469
503
|
/**
|
|
470
504
|
* Returns the bearer token currently held by the SDK, or `undefined` if none is set.
|
|
471
505
|
* In proxy mode, credentials are held by the parent frame, not the local SDK,
|
|
@@ -1107,6 +1141,10 @@ export async function request(path) {
|
|
|
1107
1141
|
headers["AUTHORIZATION"] = `Bearer ${bearerToken}`;
|
|
1108
1142
|
if (clientPlatform)
|
|
1109
1143
|
headers["X-Client-Platform"] = clientPlatform;
|
|
1144
|
+
if (grantToken)
|
|
1145
|
+
headers["X-Grant-Token"] = grantToken;
|
|
1146
|
+
if (grantToken)
|
|
1147
|
+
headers["X-Grant-Token"] = grantToken;
|
|
1110
1148
|
if (ngrokSkipBrowserWarning)
|
|
1111
1149
|
headers["ngrok-skip-browser-warning"] = "true";
|
|
1112
1150
|
const _getDomain = getSourceDomain();
|
|
@@ -1182,6 +1220,8 @@ export async function post(path, body, extraHeaders) {
|
|
|
1182
1220
|
headers["AUTHORIZATION"] = `Bearer ${bearerToken}`;
|
|
1183
1221
|
if (clientPlatform)
|
|
1184
1222
|
headers["X-Client-Platform"] = clientPlatform;
|
|
1223
|
+
if (grantToken)
|
|
1224
|
+
headers["X-Grant-Token"] = grantToken;
|
|
1185
1225
|
if (ngrokSkipBrowserWarning)
|
|
1186
1226
|
headers["ngrok-skip-browser-warning"] = "true";
|
|
1187
1227
|
const _postDomain = getSourceDomain();
|
|
@@ -1241,6 +1281,8 @@ export async function put(path, body, extraHeaders) {
|
|
|
1241
1281
|
headers["AUTHORIZATION"] = `Bearer ${bearerToken}`;
|
|
1242
1282
|
if (clientPlatform)
|
|
1243
1283
|
headers["X-Client-Platform"] = clientPlatform;
|
|
1284
|
+
if (grantToken)
|
|
1285
|
+
headers["X-Grant-Token"] = grantToken;
|
|
1244
1286
|
if (ngrokSkipBrowserWarning)
|
|
1245
1287
|
headers["ngrok-skip-browser-warning"] = "true";
|
|
1246
1288
|
const _putDomain = getSourceDomain();
|
|
@@ -1300,6 +1342,8 @@ export async function patch(path, body, extraHeaders) {
|
|
|
1300
1342
|
headers["AUTHORIZATION"] = `Bearer ${bearerToken}`;
|
|
1301
1343
|
if (clientPlatform)
|
|
1302
1344
|
headers["X-Client-Platform"] = clientPlatform;
|
|
1345
|
+
if (grantToken)
|
|
1346
|
+
headers["X-Grant-Token"] = grantToken;
|
|
1303
1347
|
if (ngrokSkipBrowserWarning)
|
|
1304
1348
|
headers["ngrok-skip-browser-warning"] = "true";
|
|
1305
1349
|
const _patchDomain = getSourceDomain();
|
|
@@ -1404,7 +1448,7 @@ export async function requestWithOptions(path, options) {
|
|
|
1404
1448
|
}
|
|
1405
1449
|
}
|
|
1406
1450
|
const _rwoDomain = getSourceDomain();
|
|
1407
|
-
const headers = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ "Content-Type": "application/json" }, (apiKey ? { "X-API-Key": apiKey } : {})), (bearerToken ? { "AUTHORIZATION": `Bearer ${bearerToken}` } : {})), (clientPlatform ? { "X-Client-Platform": clientPlatform } : {})), (ngrokSkipBrowserWarning ? { "ngrok-skip-browser-warning": "true" } : {})), (_rwoDomain ? { "X-Source-Domain": _rwoDomain } : {})), extraHeaders);
|
|
1451
|
+
const headers = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ "Content-Type": "application/json" }, (apiKey ? { "X-API-Key": apiKey } : {})), (bearerToken ? { "AUTHORIZATION": `Bearer ${bearerToken}` } : {})), (clientPlatform ? { "X-Client-Platform": clientPlatform } : {})), (grantToken ? { "X-Grant-Token": grantToken } : {})), (ngrokSkipBrowserWarning ? { "ngrok-skip-browser-warning": "true" } : {})), (_rwoDomain ? { "X-Source-Domain": _rwoDomain } : {})), extraHeaders);
|
|
1408
1452
|
// Merge global custom headers (do not override existing keys from options.headers)
|
|
1409
1453
|
for (const [k, v] of Object.entries(extraHeadersGlobal))
|
|
1410
1454
|
if (!(k in headers))
|
|
@@ -1510,6 +1554,8 @@ export async function del(path, extraHeaders) {
|
|
|
1510
1554
|
headers["AUTHORIZATION"] = `Bearer ${bearerToken}`;
|
|
1511
1555
|
if (clientPlatform)
|
|
1512
1556
|
headers["X-Client-Platform"] = clientPlatform;
|
|
1557
|
+
if (grantToken)
|
|
1558
|
+
headers["X-Grant-Token"] = grantToken;
|
|
1513
1559
|
if (ngrokSkipBrowserWarning)
|
|
1514
1560
|
headers["ngrok-skip-browser-warning"] = "true";
|
|
1515
1561
|
const _delDomain = getSourceDomain();
|
|
@@ -1552,6 +1598,8 @@ export function getApiHeaders() {
|
|
|
1552
1598
|
headers["AUTHORIZATION"] = `Bearer ${bearerToken}`;
|
|
1553
1599
|
if (clientPlatform)
|
|
1554
1600
|
headers["X-Client-Platform"] = clientPlatform;
|
|
1601
|
+
if (grantToken)
|
|
1602
|
+
headers["X-Grant-Token"] = grantToken;
|
|
1555
1603
|
if (ngrokSkipBrowserWarning)
|
|
1556
1604
|
headers["ngrok-skip-browser-warning"] = "true";
|
|
1557
1605
|
const sourceDomain = getSourceDomain();
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { initializeApi, isInitialized, hasAuthCredentials, configureSdkCache, invalidateCache, request, post, put, patch, del, sendCustomProxyMessage, getApiHeaders, isProxyEnabled, setBearerToken, getBearerToken } from "./http";
|
|
1
|
+
export { initializeApi, isInitialized, hasAuthCredentials, configureSdkCache, invalidateCache, request, post, put, patch, del, sendCustomProxyMessage, getApiHeaders, isProxyEnabled, setBearerToken, getBearerToken, setGrantToken, getGrantToken } from "./http";
|
|
2
2
|
export * from "./api";
|
|
3
3
|
export * from "./types";
|
|
4
4
|
export { iframe } from "./iframe";
|
|
@@ -17,7 +17,7 @@ export type { AdditionalGtin, ISODateString, JsonPrimitive, JsonValue, ProductCr
|
|
|
17
17
|
export type { TranslationLookupMode, TranslationContentType, TranslationQuality, TranslationItemStatus, TranslationContextValue, TranslationContext, TranslationLookupRequestBase, TranslationLookupSingleRequest, TranslationLookupBatchRequest, TranslationLookupRequest, TranslationLookupItem, TranslationLookupResponse, ResolvedTranslationItem, ResolvedTranslationResponse, TranslationHashOptions, TranslationResolveOptions, TranslationRecord, TranslationListParams, TranslationListResponse, TranslationUpdateRequest, } from "./types/translations";
|
|
18
18
|
export type { FacetBucket, FacetDefinition, FacetDefinitionWriteInput, FacetGetParams, FacetListParams, FacetListResponse, FacetNamespaceListResponse, FacetQueryRequest, FacetQueryResponse, FacetValue, FacetValueDefinition, FacetValueGetParams, FacetValueListParams, FacetValueListResponse, FacetValueResponse, FacetValueWriteInput, PublicFacetListParams, } from "./types/facets";
|
|
19
19
|
export type { Collection, CollectionResponse, CollectionCreateRequest, CollectionUpdateRequest, DomainTarget, HubAvailabilityResponse, } from "./types/collection";
|
|
20
|
-
export type { Proof, ProofResponse, ProofCreateRequest, ProofUpdateRequest, ProofClaimRequest, } from "./types/proof";
|
|
20
|
+
export type { Proof, ProofResponse, ProofCreateRequest, ProofUpdateRequest, ProofClaimRequest, ProofGrant, GrantScope, GrantAudience, CreateGrantOptions, RedeemGrantOptions, RedeemGrantResult, } from "./types/proof";
|
|
21
21
|
export type { QrShortCodeLookupResponse, } from "./types/qr";
|
|
22
22
|
export type { ReverseTagLookupParams, ReverseTagLookupResponse, } from "./types/tags";
|
|
23
23
|
export type { AdminMobileCapability, ActionableCapability, AdminMobileHostId, AdminMobileEvent, AdminMobileEventCallback, AdminMobileEventSubscriber, ScannerEventSubscriber, // @deprecated — use AdminMobileEventCallback
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
// Top-level entrypoint of the npm package. Re-export initializeApi + all namespaces.
|
|
3
|
-
export { initializeApi, isInitialized, hasAuthCredentials, configureSdkCache, invalidateCache, request, post, put, patch, del, sendCustomProxyMessage, getApiHeaders, isProxyEnabled, setBearerToken, getBearerToken } from "./http";
|
|
3
|
+
export { initializeApi, isInitialized, hasAuthCredentials, configureSdkCache, invalidateCache, request, post, put, patch, del, sendCustomProxyMessage, getApiHeaders, isProxyEnabled, setBearerToken, getBearerToken, setGrantToken, getGrantToken } from "./http";
|
|
4
4
|
export * from "./api";
|
|
5
5
|
export * from "./types";
|
|
6
6
|
// Iframe namespace
|
package/dist/openapi.yaml
CHANGED
|
@@ -12183,6 +12183,90 @@ paths:
|
|
|
12183
12183
|
application/json:
|
|
12184
12184
|
schema:
|
|
12185
12185
|
$ref: "#/components/schemas/ProofClaimRequest"
|
|
12186
|
+
/public/collection/{collectionId}/product/{productId}/proof/{proofId}/grant/redeem:
|
|
12187
|
+
post:
|
|
12188
|
+
tags:
|
|
12189
|
+
- proof
|
|
12190
|
+
summary: Redeem a grant token (anonymous or signed-in).
|
|
12191
|
+
operationId: proof_redeemGrant
|
|
12192
|
+
security: []
|
|
12193
|
+
parameters:
|
|
12194
|
+
- name: collectionId
|
|
12195
|
+
in: path
|
|
12196
|
+
required: true
|
|
12197
|
+
schema:
|
|
12198
|
+
type: string
|
|
12199
|
+
- name: productId
|
|
12200
|
+
in: path
|
|
12201
|
+
required: true
|
|
12202
|
+
schema:
|
|
12203
|
+
type: string
|
|
12204
|
+
- name: proofId
|
|
12205
|
+
in: path
|
|
12206
|
+
required: true
|
|
12207
|
+
schema:
|
|
12208
|
+
type: string
|
|
12209
|
+
responses:
|
|
12210
|
+
200:
|
|
12211
|
+
description: Success
|
|
12212
|
+
content:
|
|
12213
|
+
application/json:
|
|
12214
|
+
schema:
|
|
12215
|
+
$ref: "#/components/schemas/RedeemGrantResult"
|
|
12216
|
+
400:
|
|
12217
|
+
description: Bad request
|
|
12218
|
+
401:
|
|
12219
|
+
description: Unauthorized
|
|
12220
|
+
404:
|
|
12221
|
+
description: Not found
|
|
12222
|
+
requestBody:
|
|
12223
|
+
required: true
|
|
12224
|
+
content:
|
|
12225
|
+
application/json:
|
|
12226
|
+
schema:
|
|
12227
|
+
$ref: "#/components/schemas/RedeemGrantOptions"
|
|
12228
|
+
/public/collection/{collectionId}/product/{productId}/proof/{proofId}/grant/{grantId}:
|
|
12229
|
+
delete:
|
|
12230
|
+
tags:
|
|
12231
|
+
- proof
|
|
12232
|
+
summary: Revoke a grant by id (owner / collection admin only).
|
|
12233
|
+
operationId: proof_revokeGrant
|
|
12234
|
+
security: []
|
|
12235
|
+
parameters:
|
|
12236
|
+
- name: collectionId
|
|
12237
|
+
in: path
|
|
12238
|
+
required: true
|
|
12239
|
+
schema:
|
|
12240
|
+
type: string
|
|
12241
|
+
- name: productId
|
|
12242
|
+
in: path
|
|
12243
|
+
required: true
|
|
12244
|
+
schema:
|
|
12245
|
+
type: string
|
|
12246
|
+
- name: proofId
|
|
12247
|
+
in: path
|
|
12248
|
+
required: true
|
|
12249
|
+
schema:
|
|
12250
|
+
type: string
|
|
12251
|
+
- name: grantId
|
|
12252
|
+
in: path
|
|
12253
|
+
required: true
|
|
12254
|
+
schema:
|
|
12255
|
+
type: string
|
|
12256
|
+
responses:
|
|
12257
|
+
200:
|
|
12258
|
+
description: Success
|
|
12259
|
+
content:
|
|
12260
|
+
application/json:
|
|
12261
|
+
schema:
|
|
12262
|
+
type: object
|
|
12263
|
+
additionalProperties: true
|
|
12264
|
+
400:
|
|
12265
|
+
description: Bad request
|
|
12266
|
+
401:
|
|
12267
|
+
description: Unauthorized
|
|
12268
|
+
404:
|
|
12269
|
+
description: Not found
|
|
12186
12270
|
/public/collection/{collectionId}/products/{productId}/createClaim:
|
|
12187
12271
|
post:
|
|
12188
12272
|
tags:
|
|
@@ -13857,6 +13941,23 @@ paths:
|
|
|
13857
13941
|
required: false
|
|
13858
13942
|
schema:
|
|
13859
13943
|
type: string
|
|
13944
|
+
- name: parentIds
|
|
13945
|
+
in: query
|
|
13946
|
+
required: false
|
|
13947
|
+
schema:
|
|
13948
|
+
type: array
|
|
13949
|
+
items:
|
|
13950
|
+
type: string
|
|
13951
|
+
- name: proofId
|
|
13952
|
+
in: query
|
|
13953
|
+
required: false
|
|
13954
|
+
schema:
|
|
13955
|
+
type: string
|
|
13956
|
+
- name: productId
|
|
13957
|
+
in: query
|
|
13958
|
+
required: false
|
|
13959
|
+
schema:
|
|
13960
|
+
type: string
|
|
13860
13961
|
- name: tag
|
|
13861
13962
|
in: query
|
|
13862
13963
|
required: false
|
|
@@ -14098,6 +14199,52 @@ paths:
|
|
|
14098
14199
|
application/json:
|
|
14099
14200
|
schema:
|
|
14100
14201
|
$ref: "#/components/schemas/ReplyInput"
|
|
14202
|
+
/{zone}/collection/{collectionId}/app/{appId}/threads/{threadId}/reply/{replyId}:
|
|
14203
|
+
delete:
|
|
14204
|
+
tags:
|
|
14205
|
+
- threads
|
|
14206
|
+
summary: Delete a single reply from a thread by its reply id (moderation).
|
|
14207
|
+
operationId: threads_deleteReply
|
|
14208
|
+
security: []
|
|
14209
|
+
parameters:
|
|
14210
|
+
- name: zone
|
|
14211
|
+
in: path
|
|
14212
|
+
required: true
|
|
14213
|
+
schema:
|
|
14214
|
+
type: string
|
|
14215
|
+
- name: collectionId
|
|
14216
|
+
in: path
|
|
14217
|
+
required: true
|
|
14218
|
+
schema:
|
|
14219
|
+
type: string
|
|
14220
|
+
- name: appId
|
|
14221
|
+
in: path
|
|
14222
|
+
required: true
|
|
14223
|
+
schema:
|
|
14224
|
+
type: string
|
|
14225
|
+
- name: threadId
|
|
14226
|
+
in: path
|
|
14227
|
+
required: true
|
|
14228
|
+
schema:
|
|
14229
|
+
type: string
|
|
14230
|
+
- name: replyId
|
|
14231
|
+
in: path
|
|
14232
|
+
required: true
|
|
14233
|
+
schema:
|
|
14234
|
+
type: string
|
|
14235
|
+
responses:
|
|
14236
|
+
200:
|
|
14237
|
+
description: Success
|
|
14238
|
+
content:
|
|
14239
|
+
application/json:
|
|
14240
|
+
schema:
|
|
14241
|
+
$ref: "#/components/schemas/AppThread"
|
|
14242
|
+
400:
|
|
14243
|
+
description: Bad request
|
|
14244
|
+
401:
|
|
14245
|
+
description: Unauthorized
|
|
14246
|
+
404:
|
|
14247
|
+
description: Not found
|
|
14101
14248
|
components:
|
|
14102
14249
|
securitySchemes:
|
|
14103
14250
|
bearerAuth:
|
|
@@ -16883,6 +17030,8 @@ components:
|
|
|
16883
17030
|
admin:
|
|
16884
17031
|
type: object
|
|
16885
17032
|
additionalProperties: true
|
|
17033
|
+
firstReply:
|
|
17034
|
+
$ref: "#/components/schemas/ReplyInput"
|
|
16886
17035
|
UpdateThreadInput:
|
|
16887
17036
|
type: object
|
|
16888
17037
|
properties:
|
|
@@ -16928,6 +17077,14 @@ components:
|
|
|
16928
17077
|
type: string
|
|
16929
17078
|
parentId:
|
|
16930
17079
|
type: string
|
|
17080
|
+
parentIds:
|
|
17081
|
+
type: array
|
|
17082
|
+
items:
|
|
17083
|
+
type: string
|
|
17084
|
+
proofId:
|
|
17085
|
+
type: string
|
|
17086
|
+
productId:
|
|
17087
|
+
type: string
|
|
16931
17088
|
tag:
|
|
16932
17089
|
type: string
|
|
16933
17090
|
contactId:
|
|
@@ -24865,6 +25022,80 @@ components:
|
|
|
24865
25022
|
$ref: "#/components/schemas/ProofFieldDef"
|
|
24866
25023
|
required:
|
|
24867
25024
|
- fields
|
|
25025
|
+
GrantAudience:
|
|
25026
|
+
type: object
|
|
25027
|
+
properties:
|
|
25028
|
+
kind:
|
|
25029
|
+
type: string
|
|
25030
|
+
enum:
|
|
25031
|
+
- public_link
|
|
25032
|
+
- named
|
|
25033
|
+
email:
|
|
25034
|
+
type: string
|
|
25035
|
+
userId:
|
|
25036
|
+
type: string
|
|
25037
|
+
required:
|
|
25038
|
+
- kind
|
|
25039
|
+
ProofGrant:
|
|
25040
|
+
type: object
|
|
25041
|
+
properties:
|
|
25042
|
+
grantId:
|
|
25043
|
+
type: string
|
|
25044
|
+
proofId:
|
|
25045
|
+
type: string
|
|
25046
|
+
productId:
|
|
25047
|
+
type: string
|
|
25048
|
+
scope:
|
|
25049
|
+
type: array
|
|
25050
|
+
items:
|
|
25051
|
+
$ref: "#/components/schemas/GrantScope"
|
|
25052
|
+
audience:
|
|
25053
|
+
$ref: "#/components/schemas/GrantAudience"
|
|
25054
|
+
createdBy:
|
|
25055
|
+
type: string
|
|
25056
|
+
expiresAt:
|
|
25057
|
+
type: string
|
|
25058
|
+
revokedAt:
|
|
25059
|
+
type: string
|
|
25060
|
+
redeemedBy:
|
|
25061
|
+
type: object
|
|
25062
|
+
additionalProperties: true
|
|
25063
|
+
redeemCount:
|
|
25064
|
+
type: number
|
|
25065
|
+
createdAt:
|
|
25066
|
+
type: string
|
|
25067
|
+
updatedAt:
|
|
25068
|
+
type: string
|
|
25069
|
+
token:
|
|
25070
|
+
type: string
|
|
25071
|
+
required:
|
|
25072
|
+
- grantId
|
|
25073
|
+
- proofId
|
|
25074
|
+
- scope
|
|
25075
|
+
- audience
|
|
25076
|
+
- createdBy
|
|
25077
|
+
- redeemCount
|
|
25078
|
+
- createdAt
|
|
25079
|
+
- updatedAt
|
|
25080
|
+
CreateGrantOptions:
|
|
25081
|
+
type: object
|
|
25082
|
+
properties:
|
|
25083
|
+
scope:
|
|
25084
|
+
type: array
|
|
25085
|
+
items:
|
|
25086
|
+
$ref: "#/components/schemas/GrantScope"
|
|
25087
|
+
audience:
|
|
25088
|
+
$ref: "#/components/schemas/GrantAudience"
|
|
25089
|
+
expiresAt:
|
|
25090
|
+
type: object
|
|
25091
|
+
additionalProperties: true
|
|
25092
|
+
required:
|
|
25093
|
+
- scope
|
|
25094
|
+
RedeemGrantOptions:
|
|
25095
|
+
type: object
|
|
25096
|
+
properties:
|
|
25097
|
+
guestName:
|
|
25098
|
+
type: string
|
|
24868
25099
|
ProofResponse:
|
|
24869
25100
|
type: object
|
|
24870
25101
|
additionalProperties: true
|