@sparkvault/sdk-mobile 7.0.1 → 7.0.2

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.
@@ -12,7 +12,18 @@
12
12
  */
13
13
  export function uploadTransferReference(istk: string): string;
14
14
  /**
15
- * The upload publication contract between Forge and Core's activation.
15
+ * Why Core revoked the upload token a forge-transactions record is
16
+ * (UPLOAD_TOKEN_REVOCATION's reasons), or null for any other record, or none:
17
+ * the one reading Core's mint and every Forge read of a token apply.
18
+ *
19
+ * @param {Object|null|undefined} record - A forge-transactions record, or none
20
+ * @returns {string|null}
21
+ */
22
+ export function uploadTokenRevocationReason(record: Object | null | undefined): string | null;
23
+ /**
24
+ * The upload publication contract between Forge and Core's activation, and
25
+ * the facts of a transfer token both services spell: its shape, and Core's
26
+ * revocation of an upload's token.
16
27
  *
17
28
  * Forge stamps UPLOAD_PUBLICATION_PROTOCOL on every upload session it creates
18
29
  * and on the final state it hands Core's activation (POST
@@ -38,6 +49,15 @@ export const UPLOAD_PUBLICATION_PROTOCOL: 2;
38
49
  * the session's id.
39
50
  */
40
51
  export const UPLOAD_ID_PATTERN: RegExp;
52
+ /** The random bytes an ISTK, the bearer token of one Forge transfer, is spelled from. */
53
+ export const ISTK_BYTES: 32;
54
+ /**
55
+ * An ISTK as Core mints one: the unpadded base64url of its ISTK_BYTES random
56
+ * bytes, 43 characters. Forge reads a presented token as a forge-transactions
57
+ * key only in this shape: the table keys other records too (an upload's token
58
+ * pointer, `UPLOAD_TOKEN#{upload_id}`), which no request may read as a token.
59
+ */
60
+ export const ISTK_PATTERN: RegExp;
41
61
  /**
42
62
  * How much of an ISTK names a transfer's charge on the usage ledger: enough to
43
63
  * be unique to the token, never the whole bearer credential.
@@ -72,6 +92,37 @@ export const UPLOAD_REFUSAL_CODES: Readonly<{
72
92
  * any other a gone session.
73
93
  */
74
94
  export const UPLOAD_FINAL_REFUSAL_CODES: readonly ("UPLOAD_SUPERSEDED" | "UPLOAD_POOL_FULL")[];
95
+ /**
96
+ * The words an upload a later staging of its ingot superseded is refused in
97
+ * (UPLOAD_SUPERSEDED), whichever service meets it: Core's activation, Core's
98
+ * mint of a token it revoked before issuing it, and Forge meeting a token Core
99
+ * revoked when the later staging superseded its upload.
100
+ */
101
+ export const UPLOAD_SUPERSEDED_MESSAGE: "A later upload replaced this one before it finished. The later upload is the one kept, so this one was discarded.";
102
+ /**
103
+ * Core's revocation of an upload's encrypt token: the `status` it writes on
104
+ * the token's forge-transactions record, and the `revoked_reason` beside it,
105
+ * written by the write that ends the upload's staging. Each reason is the
106
+ * refusal every reader of the token answers the upload with from then on,
107
+ * as Core's activation refuses such an upload: Core's mint of a token it
108
+ * revoked before issuing it, and Forge on every request the token, or a
109
+ * session it opened, makes.
110
+ *
111
+ * - UPLOAD_SUPERSEDED: a later staging of its ingot superseded the upload
112
+ * (410 UPLOAD_SUPERSEDED, in UPLOAD_SUPERSEDED_MESSAGE's words), which no
113
+ * new upload remedies;
114
+ * - INGOT_DELETED: the ingot it was staged onto was deleted, by a delete or
115
+ * the cascade of its folder, vault or account (a 404 naming the ingot, as
116
+ * activation answers an upload whose ingot is gone), which ends the upload
117
+ * alone: a new upload can store the file again.
118
+ */
119
+ export const UPLOAD_TOKEN_REVOCATION: Readonly<{
120
+ status: "revoked";
121
+ reasons: Readonly<{
122
+ UPLOAD_SUPERSEDED: "UPLOAD_SUPERSEDED";
123
+ INGOT_DELETED: "INGOT_DELETED";
124
+ }>;
125
+ }>;
75
126
  /**
76
127
  * The response header that names the code Core refused an upload with for
77
128
  * good: Forge sends it on every terminal answer to a tus request, a HEAD's
@@ -2,7 +2,9 @@
2
2
  // Source of truth: packages/app-sdk/src/upload-publication.js
3
3
  // Regenerate with: pnpm --filter @sparkvault/sdk-mobile build
4
4
  /**
5
- * The upload publication contract between Forge and Core's activation.
5
+ * The upload publication contract between Forge and Core's activation, and
6
+ * the facts of a transfer token both services spell: its shape, and Core's
7
+ * revocation of an upload's token.
6
8
  *
7
9
  * Forge stamps UPLOAD_PUBLICATION_PROTOCOL on every upload session it creates
8
10
  * and on the final state it hands Core's activation (POST
@@ -28,6 +30,15 @@ export const UPLOAD_PUBLICATION_PROTOCOL = 2;
28
30
  * the session's id.
29
31
  */
30
32
  export const UPLOAD_ID_PATTERN = /^tus_[0-9a-f]{32}$/;
33
+ /** The random bytes an ISTK, the bearer token of one Forge transfer, is spelled from. */
34
+ export const ISTK_BYTES = 32;
35
+ /**
36
+ * An ISTK as Core mints one: the unpadded base64url of its ISTK_BYTES random
37
+ * bytes, 43 characters. Forge reads a presented token as a forge-transactions
38
+ * key only in this shape: the table keys other records too (an upload's token
39
+ * pointer, `UPLOAD_TOKEN#{upload_id}`), which no request may read as a token.
40
+ */
41
+ export const ISTK_PATTERN = new RegExp(`^[A-Za-z0-9_-]{${Math.ceil((ISTK_BYTES * 4) / 3)}}$`);
31
42
  /**
32
43
  * How much of an ISTK names a transfer's charge on the usage ledger: enough to
33
44
  * be unique to the token, never the whole bearer credential.
@@ -83,6 +94,51 @@ export const UPLOAD_FINAL_REFUSAL_CODES = Object.freeze([
83
94
  UPLOAD_REFUSAL_CODES.UPLOAD_POOL_FULL,
84
95
  UPLOAD_REFUSAL_CODES.UPLOAD_SUPERSEDED
85
96
  ]);
97
+ /**
98
+ * The words an upload a later staging of its ingot superseded is refused in
99
+ * (UPLOAD_SUPERSEDED), whichever service meets it: Core's activation, Core's
100
+ * mint of a token it revoked before issuing it, and Forge meeting a token Core
101
+ * revoked when the later staging superseded its upload.
102
+ */
103
+ export const UPLOAD_SUPERSEDED_MESSAGE = 'A later upload replaced this one before it finished. The later upload is the one kept, so this one was discarded.';
104
+ /**
105
+ * Core's revocation of an upload's encrypt token: the `status` it writes on
106
+ * the token's forge-transactions record, and the `revoked_reason` beside it,
107
+ * written by the write that ends the upload's staging. Each reason is the
108
+ * refusal every reader of the token answers the upload with from then on,
109
+ * as Core's activation refuses such an upload: Core's mint of a token it
110
+ * revoked before issuing it, and Forge on every request the token, or a
111
+ * session it opened, makes.
112
+ *
113
+ * - UPLOAD_SUPERSEDED: a later staging of its ingot superseded the upload
114
+ * (410 UPLOAD_SUPERSEDED, in UPLOAD_SUPERSEDED_MESSAGE's words), which no
115
+ * new upload remedies;
116
+ * - INGOT_DELETED: the ingot it was staged onto was deleted, by a delete or
117
+ * the cascade of its folder, vault or account (a 404 naming the ingot, as
118
+ * activation answers an upload whose ingot is gone), which ends the upload
119
+ * alone: a new upload can store the file again.
120
+ */
121
+ export const UPLOAD_TOKEN_REVOCATION = Object.freeze({
122
+ status: 'revoked',
123
+ reasons: Object.freeze({
124
+ UPLOAD_SUPERSEDED: UPLOAD_REFUSAL_CODES.UPLOAD_SUPERSEDED,
125
+ INGOT_DELETED: 'INGOT_DELETED'
126
+ })
127
+ });
128
+ const REVOCATION_REASONS = Object.values(UPLOAD_TOKEN_REVOCATION.reasons);
129
+ /**
130
+ * Why Core revoked the upload token a forge-transactions record is
131
+ * (UPLOAD_TOKEN_REVOCATION's reasons), or null for any other record, or none:
132
+ * the one reading Core's mint and every Forge read of a token apply.
133
+ *
134
+ * @param {Object|null|undefined} record - A forge-transactions record, or none
135
+ * @returns {string|null}
136
+ */
137
+ export function uploadTokenRevocationReason(record) {
138
+ if (record?.status !== UPLOAD_TOKEN_REVOCATION.status)
139
+ return null;
140
+ return REVOCATION_REASONS.includes(record.revoked_reason) ? record.revoked_reason : null;
141
+ }
86
142
  /**
87
143
  * The response header that names the code Core refused an upload with for
88
144
  * good: Forge sends it on every terminal answer to a tus request, a HEAD's
@@ -1 +1 @@
1
- {"version":3,"file":"upload-publication.js","sourceRoot":"","sources":["../../src/app-sdk/upload-publication.js"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,8DAA8D;AAC9D,8DAA8D;AAE9D;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC;AAE7C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,oBAAoB,CAAC;AAEtD;;;GAGG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,EAAE,CAAC;AAEhD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAI;IAC1C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,6BAA6B,EAAE,CAAC;QAC5E,MAAM,IAAI,SAAS,CACjB,+EAA+E,6BAA6B,aAAa,CAC1H,CAAC;IACJ,CAAC;IACD,OAAO,+BAA+B,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,6BAA6B,CAAC,EAAE,CAAC;AACvF,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,CAAC;IAChD,wBAAwB,EAAE,0BAA0B;IACpD,uBAAuB,EAAE,yBAAyB;IAClD,iBAAiB,EAAE,mBAAmB;IACtC,gBAAgB,EAAE,kBAAkB;CACrC,CAAC,CAAC;AAEH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC,MAAM,CAAC;IACtD,oBAAoB,CAAC,gBAAgB;IACrC,oBAAoB,CAAC,iBAAiB;CACvC,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CAAC"}
1
+ {"version":3,"file":"upload-publication.js","sourceRoot":"","sources":["../../src/app-sdk/upload-publication.js"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,8DAA8D;AAC9D,8DAA8D;AAE9D;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC;AAE7C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,oBAAoB,CAAC;AAEtD,yFAAyF;AACzF,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAC;AAE7B;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,MAAM,CAAC,kBAAkB,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AAE9F;;;GAGG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,EAAE,CAAC;AAEhD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAI;IAC1C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,6BAA6B,EAAE,CAAC;QAC5E,MAAM,IAAI,SAAS,CACjB,+EAA+E,6BAA6B,aAAa,CAC1H,CAAC;IACJ,CAAC;IACD,OAAO,+BAA+B,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,6BAA6B,CAAC,EAAE,CAAC;AACvF,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,CAAC;IAChD,wBAAwB,EAAE,0BAA0B;IACpD,uBAAuB,EAAE,yBAAyB;IAClD,iBAAiB,EAAE,mBAAmB;IACtC,gBAAgB,EAAE,kBAAkB;CACrC,CAAC,CAAC;AAEH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC,MAAM,CAAC;IACtD,oBAAoB,CAAC,gBAAgB;IACrC,oBAAoB,CAAC,iBAAiB;CACvC,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GACpC,mHAAmH,CAAC;AAEtH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC,MAAM,CAAC;IACnD,MAAM,EAAE,SAAS;IACjB,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC;QACrB,iBAAiB,EAAE,oBAAoB,CAAC,iBAAiB;QACzD,aAAa,EAAE,eAAe;KAC/B,CAAC;CACH,CAAC,CAAC;AAEH,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;AAE1E;;;;;;;GAOG;AACH,MAAM,UAAU,2BAA2B,CAAC,MAAM;IAChD,IAAI,MAAM,EAAE,MAAM,KAAK,uBAAuB,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACnE,OAAO,kBAAkB,CAAC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3F,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sparkvault/sdk-mobile",
3
- "version": "7.0.1",
3
+ "version": "7.0.2",
4
4
  "description": "Mobile SDK for SparkVault Identity, vault, folder, and ingot workflows",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -3,7 +3,9 @@
3
3
  // Regenerate with: pnpm --filter @sparkvault/sdk-mobile build
4
4
 
5
5
  /**
6
- * The upload publication contract between Forge and Core's activation.
6
+ * The upload publication contract between Forge and Core's activation, and
7
+ * the facts of a transfer token both services spell: its shape, and Core's
8
+ * revocation of an upload's token.
7
9
  *
8
10
  * Forge stamps UPLOAD_PUBLICATION_PROTOCOL on every upload session it creates
9
11
  * and on the final state it hands Core's activation (POST
@@ -32,6 +34,17 @@ export const UPLOAD_PUBLICATION_PROTOCOL = 2;
32
34
  */
33
35
  export const UPLOAD_ID_PATTERN = /^tus_[0-9a-f]{32}$/;
34
36
 
37
+ /** The random bytes an ISTK, the bearer token of one Forge transfer, is spelled from. */
38
+ export const ISTK_BYTES = 32;
39
+
40
+ /**
41
+ * An ISTK as Core mints one: the unpadded base64url of its ISTK_BYTES random
42
+ * bytes, 43 characters. Forge reads a presented token as a forge-transactions
43
+ * key only in this shape: the table keys other records too (an upload's token
44
+ * pointer, `UPLOAD_TOKEN#{upload_id}`), which no request may read as a token.
45
+ */
46
+ export const ISTK_PATTERN = new RegExp(`^[A-Za-z0-9_-]{${Math.ceil((ISTK_BYTES * 4) / 3)}}$`);
47
+
35
48
  /**
36
49
  * How much of an ISTK names a transfer's charge on the usage ledger: enough to
37
50
  * be unique to the token, never the whole bearer credential.
@@ -93,6 +106,55 @@ export const UPLOAD_FINAL_REFUSAL_CODES = Object.freeze([
93
106
  UPLOAD_REFUSAL_CODES.UPLOAD_SUPERSEDED
94
107
  ]);
95
108
 
109
+ /**
110
+ * The words an upload a later staging of its ingot superseded is refused in
111
+ * (UPLOAD_SUPERSEDED), whichever service meets it: Core's activation, Core's
112
+ * mint of a token it revoked before issuing it, and Forge meeting a token Core
113
+ * revoked when the later staging superseded its upload.
114
+ */
115
+ export const UPLOAD_SUPERSEDED_MESSAGE =
116
+ 'A later upload replaced this one before it finished. The later upload is the one kept, so this one was discarded.';
117
+
118
+ /**
119
+ * Core's revocation of an upload's encrypt token: the `status` it writes on
120
+ * the token's forge-transactions record, and the `revoked_reason` beside it,
121
+ * written by the write that ends the upload's staging. Each reason is the
122
+ * refusal every reader of the token answers the upload with from then on,
123
+ * as Core's activation refuses such an upload: Core's mint of a token it
124
+ * revoked before issuing it, and Forge on every request the token, or a
125
+ * session it opened, makes.
126
+ *
127
+ * - UPLOAD_SUPERSEDED: a later staging of its ingot superseded the upload
128
+ * (410 UPLOAD_SUPERSEDED, in UPLOAD_SUPERSEDED_MESSAGE's words), which no
129
+ * new upload remedies;
130
+ * - INGOT_DELETED: the ingot it was staged onto was deleted, by a delete or
131
+ * the cascade of its folder, vault or account (a 404 naming the ingot, as
132
+ * activation answers an upload whose ingot is gone), which ends the upload
133
+ * alone: a new upload can store the file again.
134
+ */
135
+ export const UPLOAD_TOKEN_REVOCATION = Object.freeze({
136
+ status: 'revoked',
137
+ reasons: Object.freeze({
138
+ UPLOAD_SUPERSEDED: UPLOAD_REFUSAL_CODES.UPLOAD_SUPERSEDED,
139
+ INGOT_DELETED: 'INGOT_DELETED'
140
+ })
141
+ });
142
+
143
+ const REVOCATION_REASONS = Object.values(UPLOAD_TOKEN_REVOCATION.reasons);
144
+
145
+ /**
146
+ * Why Core revoked the upload token a forge-transactions record is
147
+ * (UPLOAD_TOKEN_REVOCATION's reasons), or null for any other record, or none:
148
+ * the one reading Core's mint and every Forge read of a token apply.
149
+ *
150
+ * @param {Object|null|undefined} record - A forge-transactions record, or none
151
+ * @returns {string|null}
152
+ */
153
+ export function uploadTokenRevocationReason(record) {
154
+ if (record?.status !== UPLOAD_TOKEN_REVOCATION.status) return null;
155
+ return REVOCATION_REASONS.includes(record.revoked_reason) ? record.revoked_reason : null;
156
+ }
157
+
96
158
  /**
97
159
  * The response header that names the code Core refused an upload with for
98
160
  * good: Forge sends it on every terminal answer to a tus request, a HEAD's