@protobase/server 0.57.1 → 0.57.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/dist/better-auth/auth-settings.d.ts +1 -1
- package/dist/better-auth/create-auth.d.ts +1 -1
- package/dist/mobile-release/release-statement.js +24 -0
- package/dist/mobile-release/release.d.ts +12 -5
- package/dist/mobile-release/release.js +22 -8
- package/dist/mobile-release.d.ts +2 -2
- package/dist/package.js +1 -1
- package/package.json +4 -4
|
@@ -1008,7 +1008,7 @@ export declare const buildAppAuth: (settings: AuthSettings, input: AppAuthInput)
|
|
|
1008
1008
|
$Infer: {
|
|
1009
1009
|
body: {
|
|
1010
1010
|
permissions: {
|
|
1011
|
-
readonly user?: ("create" | "update" | "delete" | "list" | "set-role" | "ban" | "impersonate" | "set-password" | "set-email" | "
|
|
1011
|
+
readonly user?: ("get" | "create" | "update" | "delete" | "list" | "set-role" | "ban" | "impersonate" | "set-password" | "set-email" | "impersonate-admins")[] | undefined;
|
|
1012
1012
|
readonly session?: ("delete" | "list" | "revoke")[] | undefined;
|
|
1013
1013
|
};
|
|
1014
1014
|
} & {
|
|
@@ -1133,7 +1133,7 @@ export declare const createAuth: (options: CreateAuthOptions, plugins?: AuthPlug
|
|
|
1133
1133
|
$Infer: {
|
|
1134
1134
|
body: {
|
|
1135
1135
|
permissions: {
|
|
1136
|
-
readonly user?: ("create" | "update" | "delete" | "list" | "set-role" | "ban" | "impersonate" | "set-password" | "set-email" | "
|
|
1136
|
+
readonly user?: ("get" | "create" | "update" | "delete" | "list" | "set-role" | "ban" | "impersonate" | "set-password" | "set-email" | "impersonate-admins")[] | undefined;
|
|
1137
1137
|
readonly session?: ("delete" | "list" | "revoke")[] | undefined;
|
|
1138
1138
|
};
|
|
1139
1139
|
} & {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { releaseStatementContext } from "@protobase/schema/internal";
|
|
2
|
+
import { sign } from "node:crypto";
|
|
3
|
+
//#region src/mobile-release/release-statement.ts
|
|
4
|
+
/**
|
|
5
|
+
* The statement file of a release bound to `binding`, signed with `signingKey` (see `releaseStatementFile`). The
|
|
6
|
+
* device verifies the signature over the payload's decoded bytes as they are, then parses those same bytes.
|
|
7
|
+
*/
|
|
8
|
+
const releaseStatement = (binding, signingKey) => {
|
|
9
|
+
const { manifest, order, appId, fingerprint, shellVersion } = binding;
|
|
10
|
+
const payload = Buffer.from(JSON.stringify({
|
|
11
|
+
manifest,
|
|
12
|
+
order,
|
|
13
|
+
appId,
|
|
14
|
+
fingerprint,
|
|
15
|
+
shellVersion
|
|
16
|
+
}));
|
|
17
|
+
const signature = sign("sha256", Buffer.concat([Buffer.from(releaseStatementContext), payload]), signingKey);
|
|
18
|
+
return new TextEncoder().encode(JSON.stringify({
|
|
19
|
+
payload: payload.toString("hex"),
|
|
20
|
+
signature: signature.toString("hex")
|
|
21
|
+
}));
|
|
22
|
+
};
|
|
23
|
+
//#endregion
|
|
24
|
+
export { releaseStatement };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ReleaseBinding } from "@protobase/schema/internal";
|
|
1
2
|
import { KeyObject } from "node:crypto";
|
|
2
3
|
//#region src/mobile-release/release.d.ts
|
|
3
4
|
/** A file of a release: its path inside the app's files, such as `assets/index-abc123.js`, and its bytes. */
|
|
@@ -12,13 +13,18 @@ export type ServedReleaseFile = {
|
|
|
12
13
|
signature?: string;
|
|
13
14
|
};
|
|
14
15
|
/**
|
|
15
|
-
* A release of the app's files: its bundle id, a hash of
|
|
16
|
-
* file by `href`, the manifest included.
|
|
16
|
+
* A release of the app's files: its bundle id, a hash of what binds it and of the signing key's public key, and every
|
|
17
|
+
* file by `href`, the manifest and, signed, the statement included.
|
|
17
18
|
*/
|
|
18
19
|
export type MobileRelease = {
|
|
19
20
|
bundleId: string;
|
|
20
21
|
files: Map<string, ServedReleaseFile>;
|
|
21
22
|
};
|
|
23
|
+
/** How a release is signed: the key, and what its statement binds it to beside the manifest. */
|
|
24
|
+
export type ReleaseSigning = {
|
|
25
|
+
key: KeyObject;
|
|
26
|
+
binding: Omit<ReleaseBinding, 'manifest'>;
|
|
27
|
+
};
|
|
22
28
|
/** The updater's manifest of `files`: each one's `href`, sha256 in hex and size, in the order of their hrefs. */
|
|
23
29
|
export declare const releaseManifest: (files: ReleaseFile[]) => {
|
|
24
30
|
href: string;
|
|
@@ -26,8 +32,9 @@ export declare const releaseManifest: (files: ReleaseFile[]) => {
|
|
|
26
32
|
sizeInBytes: number;
|
|
27
33
|
}[];
|
|
28
34
|
/**
|
|
29
|
-
* The release of `files`, each hashed and, with `
|
|
30
|
-
* its
|
|
35
|
+
* The release of `files`, each hashed and, with `signing`, signed once here. Its manifest is served as a file of its
|
|
36
|
+
* own and, signed, so is its statement, so a file of the app may not have their names. Signed, the id hashes the
|
|
37
|
+
* statement, which holds the manifest's hash, so the same files released in another order get another id.
|
|
31
38
|
*/
|
|
32
|
-
export declare const composeRelease: (files: ReleaseFile[],
|
|
39
|
+
export declare const composeRelease: (files: ReleaseFile[], signing?: ReleaseSigning) => MobileRelease;
|
|
33
40
|
//#endregion
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { releaseStatement } from "./release-statement.js";
|
|
2
|
+
import { releaseManifestFile, releaseStatementContext, releaseStatementFile } from "@protobase/schema/internal";
|
|
2
3
|
import { createHash, createPublicKey, sign } from "node:crypto";
|
|
3
4
|
//#region src/mobile-release/release.ts
|
|
4
5
|
const sha256 = (content) => createHash("sha256").update(content).digest("hex");
|
|
@@ -13,21 +14,34 @@ const signer = (signingKey) => signingKey ? createPublicKey(signingKey).export({
|
|
|
13
14
|
type: "spki",
|
|
14
15
|
format: "der"
|
|
15
16
|
}) : /* @__PURE__ */ new Uint8Array();
|
|
17
|
+
const context = new TextEncoder().encode(releaseStatementContext);
|
|
18
|
+
const startsWithContext = (content) => content.byteLength >= context.byteLength && context.every((byte, i) => content[i] === byte);
|
|
16
19
|
/**
|
|
17
|
-
* The release of `files`, each hashed and, with `
|
|
18
|
-
* its
|
|
20
|
+
* The release of `files`, each hashed and, with `signing`, signed once here. Its manifest is served as a file of its
|
|
21
|
+
* own and, signed, so is its statement, so a file of the app may not have their names. Signed, the id hashes the
|
|
22
|
+
* statement, which holds the manifest's hash, so the same files released in another order get another id.
|
|
19
23
|
*/
|
|
20
|
-
const composeRelease = (files,
|
|
21
|
-
if (files.some((file) => file.href ===
|
|
24
|
+
const composeRelease = (files, signing) => {
|
|
25
|
+
for (const name of [releaseManifestFile, releaseStatementFile]) if (files.some((file) => file.href === name)) throw new Error(`The app's files have a ${name}, the name of a file of the updater's: rename it`);
|
|
26
|
+
const signed = files.find((file) => startsWithContext(file.content));
|
|
27
|
+
if (signed) throw new Error(`The app's file ${signed.href} starts as a release statement's signed bytes do: change its first line`);
|
|
22
28
|
const manifest = new TextEncoder().encode(JSON.stringify(releaseManifest(files)));
|
|
29
|
+
const statement = signing && releaseStatement({
|
|
30
|
+
manifest: sha256(manifest),
|
|
31
|
+
...signing.binding
|
|
32
|
+
}, signing.key);
|
|
23
33
|
const served = (content) => ({
|
|
24
34
|
content,
|
|
25
35
|
checksum: sha256(content),
|
|
26
|
-
...
|
|
36
|
+
...signing && { signature: signature(content, signing.key) }
|
|
27
37
|
});
|
|
28
38
|
return {
|
|
29
|
-
bundleId: createHash("sha256").update(manifest).update(signer(
|
|
30
|
-
files: new Map([
|
|
39
|
+
bundleId: createHash("sha256").update(statement ?? manifest).update(signer(signing?.key)).digest("hex").slice(0, 16),
|
|
40
|
+
files: new Map([
|
|
41
|
+
...files.map(({ href, content }) => [href, served(content)]),
|
|
42
|
+
[releaseManifestFile, served(manifest)],
|
|
43
|
+
...statement ? [[releaseStatementFile, served(statement)]] : []
|
|
44
|
+
])
|
|
31
45
|
};
|
|
32
46
|
};
|
|
33
47
|
//#endregion
|
package/dist/mobile-release.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { MobileRelease, ReleaseFile, ServedReleaseFile, composeRelease, releaseManifest } from "./mobile-release/release.js";
|
|
1
|
+
import { MobileRelease, ReleaseFile, ReleaseSigning, ServedReleaseFile, composeRelease, releaseManifest } from "./mobile-release/release.js";
|
|
2
2
|
import { MobileReleaseAppInput, OfferedRelease, mobileReleaseApp } from "./mobile-release/release-app.js";
|
|
3
3
|
import { mobileSigningKeyVariable, readSigningKey } from "./mobile-release/signing-key.js";
|
|
4
4
|
import { nativeFingerprint } from "./mobile-release/fingerprint.js";
|
|
5
5
|
import { withApiOrigin } from "./mobile-release/api-origin-page.js";
|
|
6
|
-
export { type MobileRelease, type MobileReleaseAppInput, type OfferedRelease, type ReleaseFile, type ServedReleaseFile, composeRelease, mobileReleaseApp, mobileSigningKeyVariable, nativeFingerprint, readSigningKey, releaseManifest, withApiOrigin };
|
|
6
|
+
export { type MobileRelease, type MobileReleaseAppInput, type OfferedRelease, type ReleaseFile, type ReleaseSigning, type ServedReleaseFile, composeRelease, mobileReleaseApp, mobileSigningKeyVariable, nativeFingerprint, readSigningKey, releaseManifest, withApiOrigin };
|
package/dist/package.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@protobase/server",
|
|
3
|
-
"version": "0.57.
|
|
3
|
+
"version": "0.57.3",
|
|
4
4
|
"description": "The Protobase REST API as a Hono app, with Better Auth sign-in.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
"@better-auth/passkey": "^1.7.12",
|
|
42
42
|
"@better-auth/sso": "^1.7.12",
|
|
43
43
|
"@modelcontextprotocol/server": "^2.3.1",
|
|
44
|
-
"@protobase/layout": "0.57.
|
|
45
|
-
"@protobase/query": "0.57.
|
|
46
|
-
"@protobase/schema": "0.57.
|
|
44
|
+
"@protobase/layout": "0.57.3",
|
|
45
|
+
"@protobase/query": "0.57.3",
|
|
46
|
+
"@protobase/schema": "0.57.3",
|
|
47
47
|
"@react-email/render": "^2.1.0",
|
|
48
48
|
"@scalar/hono-api-reference": "^0.12.10",
|
|
49
49
|
"@sentry/core": "^11.7.0",
|