@calimero-network/mero-js 26.11.0 → 27.0.0
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 +73 -288
- package/dist/cloud-v2/attestation.d.ts +91 -0
- package/dist/cloud-v2/attestation.js +135 -0
- package/dist/cloud-v2/capabilities.d.ts +30 -0
- package/dist/cloud-v2/capabilities.js +31 -0
- package/dist/cloud-v2/client.d.ts +426 -0
- package/dist/cloud-v2/client.js +646 -0
- package/dist/cloud-v2/errors.d.ts +98 -0
- package/dist/cloud-v2/errors.js +165 -0
- package/dist/cloud-v2/index.d.ts +10 -0
- package/dist/cloud-v2/index.js +5 -0
- package/dist/cloud-v2/passkey.d.ts +27 -0
- package/dist/cloud-v2/passkey.js +73 -0
- package/dist/crypto/internal.d.ts +3 -37
- package/dist/crypto/internal.js +3 -72
- package/dist/index.browser.mjs +4 -2
- package/dist/index.browser.mjs.map +4 -4
- package/dist/index.cjs +1750 -12772
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +3 -56
- package/dist/index.js +14 -75
- package/dist/index.mjs +1750 -12772
- package/dist/index.mjs.map +4 -4
- package/dist/sealed/index.d.ts +4 -4
- package/dist/sealed/index.js +2 -2
- package/dist/sealed/release.d.ts +21 -76
- package/dist/sealed/release.js +24 -108
- package/dist/sealed/sealed.d.ts +8 -56
- package/dist/sealed/sealed.js +11 -89
- package/dist/sealed/verify.d.ts +7 -13
- package/dist/sealed/verify.js +3 -7
- package/package.json +8 -13
- package/dist/account/account-admin.d.ts +0 -80
- package/dist/account/account-admin.js +0 -346
- package/dist/account/account.d.ts +0 -196
- package/dist/account/account.js +0 -269
- package/dist/account/application-id.d.ts +0 -50
- package/dist/account/application-id.js +0 -83
- package/dist/account/bootstrap-from-invitation.d.ts +0 -110
- package/dist/account/bootstrap-from-invitation.js +0 -80
- package/dist/account/create-context.d.ts +0 -103
- package/dist/account/create-context.js +0 -267
- package/dist/account/govern.d.ts +0 -24
- package/dist/account/govern.js +0 -50
- package/dist/account/index.d.ts +0 -26
- package/dist/account/index.js +0 -15
- package/dist/account/join-as-account.d.ts +0 -23
- package/dist/account/join-as-account.js +0 -34
- package/dist/account/join-with-node.d.ts +0 -115
- package/dist/account/join-with-node.js +0 -161
- package/dist/account/node-admin.d.ts +0 -20
- package/dist/account/node-admin.js +0 -33
- package/dist/account/relay-from-invitation.d.ts +0 -137
- package/dist/account/relay-from-invitation.js +0 -180
- package/dist/account/relay-login-error.d.ts +0 -32
- package/dist/account/relay-login-error.js +0 -34
- package/dist/account/session.d.ts +0 -266
- package/dist/account/session.js +0 -915
- package/dist/account/wordlist.d.ts +0 -16
- package/dist/account/wordlist.js +0 -273
- package/dist/admin-api/admin-client.d.ts +0 -688
- package/dist/admin-api/admin-client.js +0 -1230
- package/dist/admin-api/admin-factory.d.ts +0 -14
- package/dist/admin-api/admin-factory.js +0 -22
- package/dist/admin-api/admin-types.d.ts +0 -2046
- package/dist/admin-api/admin-types.js +0 -12
- package/dist/admin-api/index.d.ts +0 -4
- package/dist/admin-api/index.js +0 -5
- package/dist/admin-api/redeem-invitation.d.ts +0 -101
- package/dist/admin-api/redeem-invitation.js +0 -200
- package/dist/auth/index.d.ts +0 -34
- package/dist/auth/index.js +0 -67
- package/dist/auth-api/auth-client.d.ts +0 -31
- package/dist/auth-api/auth-client.js +0 -117
- package/dist/auth-api/auth-factory.d.ts +0 -7
- package/dist/auth-api/auth-factory.js +0 -41
- package/dist/auth-api/auth-types.d.ts +0 -130
- package/dist/auth-api/auth-types.js +0 -2
- package/dist/auth-api/index.d.ts +0 -3
- package/dist/auth-api/index.js +0 -4
- package/dist/capabilities.d.ts +0 -84
- package/dist/capabilities.js +0 -117
- package/dist/cloud/account-ownership.d.ts +0 -63
- package/dist/cloud/account-ownership.js +0 -87
- package/dist/cloud/cloud-client.d.ts +0 -949
- package/dist/cloud/cloud-client.js +0 -1068
- package/dist/cloud/connect.d.ts +0 -213
- package/dist/cloud/connect.js +0 -260
- package/dist/cloud/enrol-redirect.d.ts +0 -181
- package/dist/cloud/enrol-redirect.js +0 -244
- package/dist/cloud/index.d.ts +0 -12
- package/dist/cloud/index.js +0 -10
- package/dist/cloud/link-redirect.d.ts +0 -95
- package/dist/cloud/link-redirect.js +0 -121
- package/dist/cloud/link-state.d.ts +0 -36
- package/dist/cloud/link-state.js +0 -104
- package/dist/cloud/routing-proof.d.ts +0 -113
- package/dist/cloud/routing-proof.js +0 -96
- package/dist/device-cert/device-cert.d.ts +0 -189
- package/dist/device-cert/device-cert.js +0 -239
- package/dist/device-cert/device-scope.d.ts +0 -58
- package/dist/device-cert/device-scope.js +0 -76
- package/dist/device-cert/index.d.ts +0 -4
- package/dist/device-cert/index.js +0 -3
- package/dist/ephemeral/codec.d.ts +0 -4
- package/dist/ephemeral/codec.js +0 -12
- package/dist/ephemeral/index.d.ts +0 -57
- package/dist/ephemeral/index.js +0 -101
- package/dist/ephemeral/types.d.ts +0 -27
- package/dist/ephemeral/types.js +0 -1
- package/dist/errors/classify.d.ts +0 -65
- package/dist/errors/classify.js +0 -117
- package/dist/errors/index.d.ts +0 -2
- package/dist/errors/index.js +0 -1
- package/dist/events/group.d.ts +0 -95
- package/dist/events/group.js +0 -10
- package/dist/events/index.d.ts +0 -5
- package/dist/events/index.js +0 -2
- package/dist/events/sse.d.ts +0 -127
- package/dist/events/sse.js +0 -469
- package/dist/events/ws.d.ts +0 -57
- package/dist/events/ws.js +0 -212
- package/dist/http-client/api-response.d.ts +0 -15
- package/dist/http-client/api-response.js +0 -1
- package/dist/http-client/http-factory.d.ts +0 -71
- package/dist/http-client/http-factory.js +0 -68
- package/dist/http-client/http-types.d.ts +0 -87
- package/dist/http-client/http-types.js +0 -1
- package/dist/http-client/index.d.ts +0 -7
- package/dist/http-client/index.js +0 -11
- package/dist/http-client/path-segment.d.ts +0 -1
- package/dist/http-client/path-segment.js +0 -8
- package/dist/http-client/retry.d.ts +0 -5
- package/dist/http-client/retry.js +0 -82
- package/dist/http-client/signal-utils.d.ts +0 -2
- package/dist/http-client/signal-utils.js +0 -41
- package/dist/http-client/web-client.d.ts +0 -80
- package/dist/http-client/web-client.js +0 -557
- package/dist/invitation/index.d.ts +0 -2
- package/dist/invitation/index.js +0 -2
- package/dist/invitation/invitation.d.ts +0 -106
- package/dist/invitation/invitation.js +0 -104
- package/dist/login/index.d.ts +0 -4
- package/dist/login/index.js +0 -3
- package/dist/login/login.d.ts +0 -111
- package/dist/login/login.js +0 -110
- package/dist/login/session.d.ts +0 -124
- package/dist/login/session.js +0 -141
- package/dist/mero-js.d.ts +0 -231
- package/dist/mero-js.js +0 -469
- package/dist/namespace-op/index.d.ts +0 -2
- package/dist/namespace-op/index.js +0 -3
- package/dist/namespace-op/namespace-op.d.ts +0 -150
- package/dist/namespace-op/namespace-op.js +0 -191
- package/dist/nodeDiscovery.d.ts +0 -47
- package/dist/nodeDiscovery.js +0 -101
- package/dist/owner-op/index.d.ts +0 -2
- package/dist/owner-op/index.js +0 -3
- package/dist/owner-op/owner-op.d.ts +0 -119
- package/dist/owner-op/owner-op.js +0 -214
- package/dist/presence/relay-presence.d.ts +0 -56
- package/dist/presence/relay-presence.js +0 -107
- package/dist/presence/statement.d.ts +0 -12
- package/dist/presence/statement.js +0 -17
- package/dist/relay/index.d.ts +0 -4
- package/dist/relay/index.js +0 -2
- package/dist/relay/nonce-source.d.ts +0 -72
- package/dist/relay/nonce-source.js +0 -111
- package/dist/relay/relay-client.d.ts +0 -472
- package/dist/relay/relay-client.js +0 -518
- package/dist/relay-attestation/attest-node-key.d.ts +0 -66
- package/dist/relay-attestation/attest-node-key.js +0 -110
- package/dist/relay-attestation/index.d.ts +0 -1
- package/dist/relay-attestation/index.js +0 -1
- package/dist/request/caller-proof.d.ts +0 -43
- package/dist/request/caller-proof.js +0 -36
- package/dist/request/index.d.ts +0 -3
- package/dist/request/index.js +0 -3
- package/dist/request/proof-signer.d.ts +0 -49
- package/dist/request/proof-signer.js +0 -59
- package/dist/request/request-sig.d.ts +0 -99
- package/dist/request/request-sig.js +0 -95
- package/dist/request-proof/authorizer.d.ts +0 -41
- package/dist/request-proof/authorizer.js +0 -60
- package/dist/request-proof/index.d.ts +0 -4
- package/dist/request-proof/index.js +0 -2
- package/dist/request-proof/request-proof.d.ts +0 -53
- package/dist/request-proof/request-proof.js +0 -95
- package/dist/rpc/index.d.ts +0 -64
- package/dist/rpc/index.js +0 -78
- package/dist/signer/index.d.ts +0 -2
- package/dist/signer/index.js +0 -3
- package/dist/signer/signer.d.ts +0 -92
- package/dist/signer/signer.js +0 -147
- package/dist/token-store/index.d.ts +0 -27
- package/dist/token-store/index.js +0 -62
- package/dist/transport/index.d.ts +0 -6
- package/dist/transport/index.js +0 -3
- package/dist/transport/mero-client.d.ts +0 -294
- package/dist/transport/mero-client.js +0 -386
- package/dist/transport/relay-observer.d.ts +0 -152
- package/dist/transport/relay-observer.js +0 -173
- package/dist/transport/relay-transport.d.ts +0 -73
- package/dist/transport/relay-transport.js +0 -94
- package/dist/transport/types.d.ts +0 -100
- package/dist/transport/types.js +0 -32
- package/dist/types/api-response.d.ts +0 -15
- package/dist/types/api-response.js +0 -1
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.js +0 -1
- package/dist/warrant/creation-warrant.d.ts +0 -163
- package/dist/warrant/creation-warrant.js +0 -194
- package/dist/warrant/governance-op.d.ts +0 -202
- package/dist/warrant/governance-op.js +0 -355
- package/dist/warrant/governance-warrant.d.ts +0 -124
- package/dist/warrant/governance-warrant.js +0 -164
- package/dist/warrant/index.d.ts +0 -8
- package/dist/warrant/index.js +0 -5
- package/dist/warrant/warrant.d.ts +0 -188
- package/dist/warrant/warrant.js +0 -202
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
export { ApiResponse } from '../http-client/index.js';
|
|
2
|
-
export interface HealthResponse {
|
|
3
|
-
status: 'alive' | 'not_alive';
|
|
4
|
-
storage: boolean;
|
|
5
|
-
uptime_seconds: number;
|
|
6
|
-
}
|
|
7
|
-
export interface IdentityResponse {
|
|
8
|
-
service: string;
|
|
9
|
-
version: string;
|
|
10
|
-
authentication_mode: string;
|
|
11
|
-
providers: string[];
|
|
12
|
-
}
|
|
13
|
-
export interface ProvidersResponse {
|
|
14
|
-
providers: Array<{
|
|
15
|
-
name: string;
|
|
16
|
-
type: string;
|
|
17
|
-
description: string;
|
|
18
|
-
configured: boolean;
|
|
19
|
-
config: Record<string, unknown>;
|
|
20
|
-
}>;
|
|
21
|
-
count: number;
|
|
22
|
-
/**
|
|
23
|
-
* App origins, besides the node's own and the registry-declared frontends,
|
|
24
|
-
* that this node's login page may hand a token pair to (`callback-url`):
|
|
25
|
-
* exact `http(s)` origins from the node's
|
|
26
|
-
* `[server.embedded_auth.development] trusted_callback_origins`. Absent on
|
|
27
|
-
* nodes from before it existed; treat that as none.
|
|
28
|
-
*/
|
|
29
|
-
trusted_callback_origins?: string[];
|
|
30
|
-
}
|
|
31
|
-
export interface TokenRequest {
|
|
32
|
-
auth_method: string;
|
|
33
|
-
public_key: string;
|
|
34
|
-
client_name: string;
|
|
35
|
-
permissions?: string[];
|
|
36
|
-
timestamp: number;
|
|
37
|
-
provider_data: Record<string, unknown>;
|
|
38
|
-
}
|
|
39
|
-
export interface TokenResponse {
|
|
40
|
-
data: {
|
|
41
|
-
access_token: string;
|
|
42
|
-
refresh_token: string;
|
|
43
|
-
error?: string | null;
|
|
44
|
-
};
|
|
45
|
-
error?: string | null;
|
|
46
|
-
}
|
|
47
|
-
export interface RefreshTokenRequest {
|
|
48
|
-
access_token: string;
|
|
49
|
-
refresh_token: string;
|
|
50
|
-
}
|
|
51
|
-
export interface MockTokenRequest {
|
|
52
|
-
client_name: string;
|
|
53
|
-
permissions?: string[];
|
|
54
|
-
node_url?: string;
|
|
55
|
-
access_token_expiry?: number;
|
|
56
|
-
refresh_token_expiry?: number;
|
|
57
|
-
}
|
|
58
|
-
export interface RevokeTokenRequest {
|
|
59
|
-
client_id: string;
|
|
60
|
-
}
|
|
61
|
-
export interface RevokeTokenResponse {
|
|
62
|
-
success: boolean;
|
|
63
|
-
message: string;
|
|
64
|
-
}
|
|
65
|
-
export interface CreateKeyRequest {
|
|
66
|
-
/** Public key to register as a root key. */
|
|
67
|
-
public_key: string;
|
|
68
|
-
/** Auth method / provider name (e.g. "user_password"). */
|
|
69
|
-
auth_method: string;
|
|
70
|
-
/** Provider-specific data. */
|
|
71
|
-
provider_data: Record<string, unknown>;
|
|
72
|
-
/** Target node URL to scope the root key to (optional). */
|
|
73
|
-
target_node_url?: string;
|
|
74
|
-
}
|
|
75
|
-
export interface CreateKeyResponse {
|
|
76
|
-
status: boolean;
|
|
77
|
-
message: string;
|
|
78
|
-
}
|
|
79
|
-
export interface DeleteKeyResponse {
|
|
80
|
-
success: boolean;
|
|
81
|
-
message: string;
|
|
82
|
-
}
|
|
83
|
-
export interface RootKey {
|
|
84
|
-
key_id: string;
|
|
85
|
-
public_key: string;
|
|
86
|
-
auth_method: string;
|
|
87
|
-
created_at: number;
|
|
88
|
-
revoked_at?: number | null;
|
|
89
|
-
permissions: string[];
|
|
90
|
-
}
|
|
91
|
-
export interface ClientKey {
|
|
92
|
-
client_id: string;
|
|
93
|
-
root_key_id: string;
|
|
94
|
-
name: string;
|
|
95
|
-
permissions: string[];
|
|
96
|
-
created_at: number;
|
|
97
|
-
revoked_at?: number | null;
|
|
98
|
-
is_valid: boolean;
|
|
99
|
-
}
|
|
100
|
-
export interface GenerateClientKeyRequest {
|
|
101
|
-
/** Context the client key is scoped to (optional). */
|
|
102
|
-
context_id?: string;
|
|
103
|
-
/** Context identity (executor public key) the client key is for (optional). */
|
|
104
|
-
context_identity?: string;
|
|
105
|
-
/** Additional permissions to request (validated against the root key). */
|
|
106
|
-
permissions?: string[];
|
|
107
|
-
/** Target node URL to scope the client key/tokens to (optional). */
|
|
108
|
-
target_node_url?: string;
|
|
109
|
-
}
|
|
110
|
-
export interface DeleteClientResponse {
|
|
111
|
-
success: boolean;
|
|
112
|
-
message: string;
|
|
113
|
-
}
|
|
114
|
-
export interface UpdateKeyPermissionsRequest {
|
|
115
|
-
/** Permission strings to add (OR-ed onto the key's current set). */
|
|
116
|
-
add?: string[];
|
|
117
|
-
/** Permission strings to remove (applied before `add`). */
|
|
118
|
-
remove?: string[];
|
|
119
|
-
}
|
|
120
|
-
export interface PermissionResponse {
|
|
121
|
-
data: {
|
|
122
|
-
permissions: string[];
|
|
123
|
-
};
|
|
124
|
-
error?: string | null;
|
|
125
|
-
}
|
|
126
|
-
export interface AuthApiClientConfig {
|
|
127
|
-
baseUrl: string;
|
|
128
|
-
getAuthToken?: () => Promise<string | undefined>;
|
|
129
|
-
timeoutMs?: number;
|
|
130
|
-
}
|
package/dist/auth-api/index.d.ts
DELETED
package/dist/auth-api/index.js
DELETED
package/dist/capabilities.d.ts
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Capability bits as defined by core's `MemberCapabilities`.
|
|
3
|
-
*
|
|
4
|
-
* The per-member value is a u32 bitmask. Core currently assigns bits 0..=9
|
|
5
|
-
* (the entries below); bits 10 and above are unassigned — do not repurpose
|
|
6
|
-
* them for application data, as a future core release may claim them.
|
|
7
|
-
*/
|
|
8
|
-
export declare const CAPABILITIES: {
|
|
9
|
-
readonly CAN_CREATE_CONTEXT: number;
|
|
10
|
-
readonly CAN_INVITE_MEMBERS: number;
|
|
11
|
-
readonly CAN_JOIN_OPEN_SUBGROUPS: number;
|
|
12
|
-
readonly MANAGE_MEMBERS: number;
|
|
13
|
-
readonly MANAGE_APPLICATION: number;
|
|
14
|
-
readonly CAN_CREATE_SUBGROUP: number;
|
|
15
|
-
readonly CAN_DELETE_SUBGROUP: number;
|
|
16
|
-
readonly CAN_MANAGE_VISIBILITY: number;
|
|
17
|
-
readonly CAN_MANAGE_METADATA: number;
|
|
18
|
-
/**
|
|
19
|
-
* Publish writes attributed to ANOTHER member, under a warrant that member
|
|
20
|
-
* signed — the grant delegated execution runs on.
|
|
21
|
-
*
|
|
22
|
-
* Implied by nothing: not by membership, not by admin, and not propagated by
|
|
23
|
-
* the subgroup-admit cascade. So every group is authorship-closed until an
|
|
24
|
-
* admin sets this bit, and a relay without it is refused at
|
|
25
|
-
* `performIntent` before anything executes. That is why it is worth naming
|
|
26
|
-
* here rather than leaving callers to write `1 << 9`: a client granting it
|
|
27
|
-
* has to be able to say what it is granting.
|
|
28
|
-
*/
|
|
29
|
-
readonly CAN_AUTHOR_ON_BEHALF: number;
|
|
30
|
-
};
|
|
31
|
-
export type CapabilityName = keyof typeof CAPABILITIES;
|
|
32
|
-
export type CapabilityBit = (typeof CAPABILITIES)[CapabilityName];
|
|
33
|
-
/**
|
|
34
|
-
* Ready-made masks for `setDefaultCapabilities` / `setMemberCapabilities` and
|
|
35
|
-
* `RelayClient.foundNamespace({ defaultCapabilities })`, so an app can name the
|
|
36
|
-
* default it gives members instead of passing a bare number.
|
|
37
|
-
*
|
|
38
|
-
* Why this matters: a namespace's default mask is copied into a non-admin
|
|
39
|
-
* member's row when they join, and a namespace starts without
|
|
40
|
-
* `CAN_CREATE_CONTEXT` in it. An app that never sets a default leaves every
|
|
41
|
-
* invited member unable to create a context until an admin grants it by hand.
|
|
42
|
-
*
|
|
43
|
-
* None of these include `CAN_AUTHOR_ON_BEHALF`; grant that deliberately (see
|
|
44
|
-
* `AdminApiClient.grantAuthorship` / `openToDelegatedExecution`).
|
|
45
|
-
*/
|
|
46
|
-
export declare const CAPABILITY_PRESETS: {
|
|
47
|
-
/** No capabilities. */
|
|
48
|
-
readonly NONE: 0;
|
|
49
|
-
/** Join Open subgroups only: what a namespace starts with. */
|
|
50
|
-
readonly JOIN_ONLY: number;
|
|
51
|
-
/**
|
|
52
|
-
* Create contexts, invite members, join Open subgroups (= 7). A member who
|
|
53
|
-
* can work in the namespace but not reshape it.
|
|
54
|
-
*/
|
|
55
|
-
readonly CONTRIBUTOR: number;
|
|
56
|
-
/**
|
|
57
|
-
* `CONTRIBUTOR` plus create and delete subgroups and manage their visibility
|
|
58
|
-
* (= 231). What mero-chat gives members, so they can start and close their
|
|
59
|
-
* own channels.
|
|
60
|
-
*/
|
|
61
|
-
readonly COLLABORATOR: number;
|
|
62
|
-
};
|
|
63
|
-
export type CapabilityPreset = keyof typeof CAPABILITY_PRESETS;
|
|
64
|
-
/**
|
|
65
|
-
* Builds a u32 mask from capability names and/or bit values:
|
|
66
|
-
* `capMask('CAN_CREATE_CONTEXT', 'CAN_INVITE_MEMBERS') === 3`.
|
|
67
|
-
* Throws on a name core does not assign, so a typo can't silently yield 0.
|
|
68
|
-
*/
|
|
69
|
-
export declare function capMask(...caps: Array<CapabilityName | number>): number;
|
|
70
|
-
/**
|
|
71
|
-
* The names of the assigned capability bits set in `mask`, in bit order.
|
|
72
|
-
* Unassigned bits (10 and above) are not reported.
|
|
73
|
-
*/
|
|
74
|
-
export declare function capNames(mask: number): CapabilityName[];
|
|
75
|
-
/**
|
|
76
|
-
* Returns true if `mask` has every bit of `cap` set. Both operands are
|
|
77
|
-
* coerced to unsigned 32-bit (`>>> 0`) before comparing so a high bit such
|
|
78
|
-
* as `1 << 31` doesn't fall foul of `&` yielding a signed result.
|
|
79
|
-
*/
|
|
80
|
-
export declare function hasCap(mask: number, cap: number): boolean;
|
|
81
|
-
/** Returns `mask` with every bit of `cap` set (u32-normalized). */
|
|
82
|
-
export declare function withCap(mask: number, cap: number): number;
|
|
83
|
-
/** Returns `mask` with every bit of `cap` cleared (u32-normalized). */
|
|
84
|
-
export declare function withoutCap(mask: number, cap: number): number;
|
package/dist/capabilities.js
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
// Member capability bitmask constants — mirrors core's `MemberCapabilities`
|
|
2
|
-
// (crates/context/config/src/lib.rs). The value stored per-member is a u32
|
|
3
|
-
// bitmask. Core currently assigns bits 0..=9; bits 10 and above are unassigned
|
|
4
|
-
// and may be claimed by future core versions, so an application MUST NOT
|
|
5
|
-
// assume any particular bit is safe for its own use unless core documents it
|
|
6
|
-
// as reserved for applications.
|
|
7
|
-
/**
|
|
8
|
-
* Capability bits as defined by core's `MemberCapabilities`.
|
|
9
|
-
*
|
|
10
|
-
* The per-member value is a u32 bitmask. Core currently assigns bits 0..=9
|
|
11
|
-
* (the entries below); bits 10 and above are unassigned — do not repurpose
|
|
12
|
-
* them for application data, as a future core release may claim them.
|
|
13
|
-
*/
|
|
14
|
-
export const CAPABILITIES = {
|
|
15
|
-
CAN_CREATE_CONTEXT: 1 << 0,
|
|
16
|
-
CAN_INVITE_MEMBERS: 1 << 1,
|
|
17
|
-
CAN_JOIN_OPEN_SUBGROUPS: 1 << 2,
|
|
18
|
-
MANAGE_MEMBERS: 1 << 3,
|
|
19
|
-
MANAGE_APPLICATION: 1 << 4,
|
|
20
|
-
CAN_CREATE_SUBGROUP: 1 << 5,
|
|
21
|
-
CAN_DELETE_SUBGROUP: 1 << 6,
|
|
22
|
-
CAN_MANAGE_VISIBILITY: 1 << 7,
|
|
23
|
-
CAN_MANAGE_METADATA: 1 << 8,
|
|
24
|
-
/**
|
|
25
|
-
* Publish writes attributed to ANOTHER member, under a warrant that member
|
|
26
|
-
* signed — the grant delegated execution runs on.
|
|
27
|
-
*
|
|
28
|
-
* Implied by nothing: not by membership, not by admin, and not propagated by
|
|
29
|
-
* the subgroup-admit cascade. So every group is authorship-closed until an
|
|
30
|
-
* admin sets this bit, and a relay without it is refused at
|
|
31
|
-
* `performIntent` before anything executes. That is why it is worth naming
|
|
32
|
-
* here rather than leaving callers to write `1 << 9`: a client granting it
|
|
33
|
-
* has to be able to say what it is granting.
|
|
34
|
-
*/
|
|
35
|
-
CAN_AUTHOR_ON_BEHALF: 1 << 9,
|
|
36
|
-
};
|
|
37
|
-
/**
|
|
38
|
-
* Ready-made masks for `setDefaultCapabilities` / `setMemberCapabilities` and
|
|
39
|
-
* `RelayClient.foundNamespace({ defaultCapabilities })`, so an app can name the
|
|
40
|
-
* default it gives members instead of passing a bare number.
|
|
41
|
-
*
|
|
42
|
-
* Why this matters: a namespace's default mask is copied into a non-admin
|
|
43
|
-
* member's row when they join, and a namespace starts without
|
|
44
|
-
* `CAN_CREATE_CONTEXT` in it. An app that never sets a default leaves every
|
|
45
|
-
* invited member unable to create a context until an admin grants it by hand.
|
|
46
|
-
*
|
|
47
|
-
* None of these include `CAN_AUTHOR_ON_BEHALF`; grant that deliberately (see
|
|
48
|
-
* `AdminApiClient.grantAuthorship` / `openToDelegatedExecution`).
|
|
49
|
-
*/
|
|
50
|
-
export const CAPABILITY_PRESETS = {
|
|
51
|
-
/** No capabilities. */
|
|
52
|
-
NONE: 0,
|
|
53
|
-
/** Join Open subgroups only: what a namespace starts with. */
|
|
54
|
-
JOIN_ONLY: CAPABILITIES.CAN_JOIN_OPEN_SUBGROUPS,
|
|
55
|
-
/**
|
|
56
|
-
* Create contexts, invite members, join Open subgroups (= 7). A member who
|
|
57
|
-
* can work in the namespace but not reshape it.
|
|
58
|
-
*/
|
|
59
|
-
CONTRIBUTOR: CAPABILITIES.CAN_CREATE_CONTEXT |
|
|
60
|
-
CAPABILITIES.CAN_INVITE_MEMBERS |
|
|
61
|
-
CAPABILITIES.CAN_JOIN_OPEN_SUBGROUPS,
|
|
62
|
-
/**
|
|
63
|
-
* `CONTRIBUTOR` plus create and delete subgroups and manage their visibility
|
|
64
|
-
* (= 231). What mero-chat gives members, so they can start and close their
|
|
65
|
-
* own channels.
|
|
66
|
-
*/
|
|
67
|
-
COLLABORATOR: CAPABILITIES.CAN_CREATE_CONTEXT |
|
|
68
|
-
CAPABILITIES.CAN_INVITE_MEMBERS |
|
|
69
|
-
CAPABILITIES.CAN_JOIN_OPEN_SUBGROUPS |
|
|
70
|
-
CAPABILITIES.CAN_CREATE_SUBGROUP |
|
|
71
|
-
CAPABILITIES.CAN_DELETE_SUBGROUP |
|
|
72
|
-
CAPABILITIES.CAN_MANAGE_VISIBILITY,
|
|
73
|
-
};
|
|
74
|
-
/**
|
|
75
|
-
* Builds a u32 mask from capability names and/or bit values:
|
|
76
|
-
* `capMask('CAN_CREATE_CONTEXT', 'CAN_INVITE_MEMBERS') === 3`.
|
|
77
|
-
* Throws on a name core does not assign, so a typo can't silently yield 0.
|
|
78
|
-
*/
|
|
79
|
-
export function capMask(...caps) {
|
|
80
|
-
let mask = 0;
|
|
81
|
-
for (const cap of caps) {
|
|
82
|
-
if (typeof cap === 'number') {
|
|
83
|
-
mask |= cap;
|
|
84
|
-
}
|
|
85
|
-
else if (Object.prototype.hasOwnProperty.call(CAPABILITIES, cap)) {
|
|
86
|
-
mask |= CAPABILITIES[cap];
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
throw new Error(`unknown capability: ${String(cap)}`);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return mask >>> 0;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* The names of the assigned capability bits set in `mask`, in bit order.
|
|
96
|
-
* Unassigned bits (10 and above) are not reported.
|
|
97
|
-
*/
|
|
98
|
-
export function capNames(mask) {
|
|
99
|
-
return Object.keys(CAPABILITIES).filter((name) => hasCap(mask, CAPABILITIES[name]));
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Returns true if `mask` has every bit of `cap` set. Both operands are
|
|
103
|
-
* coerced to unsigned 32-bit (`>>> 0`) before comparing so a high bit such
|
|
104
|
-
* as `1 << 31` doesn't fall foul of `&` yielding a signed result.
|
|
105
|
-
*/
|
|
106
|
-
export function hasCap(mask, cap) {
|
|
107
|
-
const capU32 = cap >>> 0;
|
|
108
|
-
return ((mask & capU32) >>> 0) === capU32;
|
|
109
|
-
}
|
|
110
|
-
/** Returns `mask` with every bit of `cap` set (u32-normalized). */
|
|
111
|
-
export function withCap(mask, cap) {
|
|
112
|
-
return (mask | cap) >>> 0;
|
|
113
|
-
}
|
|
114
|
-
/** Returns `mask` with every bit of `cap` cleared (u32-normalized). */
|
|
115
|
-
export function withoutCap(mask, cap) {
|
|
116
|
-
return (mask & ~cap) >>> 0;
|
|
117
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { type Signer } from '../signer/signer.js';
|
|
2
|
-
/**
|
|
3
|
-
* The `ownership_proof` body for `POST /api/cloud/me/namespaces/{ns}/enable-ha`
|
|
4
|
-
* and for `POST /api/cloud/accounts/{account}/namespaces/{ns}/enable-ha`.
|
|
5
|
-
*/
|
|
6
|
-
export interface AccountOwnershipProof {
|
|
7
|
-
kind: 'account';
|
|
8
|
-
/** hex `AccountProof<DeviceCert>`, the account's credential. */
|
|
9
|
-
credential: string;
|
|
10
|
-
/** base64 UTF-8 JSON, the claim. */
|
|
11
|
-
signed_payload: string;
|
|
12
|
-
/** base64 ed25519 by the certified device key. */
|
|
13
|
-
signature: string;
|
|
14
|
-
}
|
|
15
|
-
/** What every account claim needs; the audience and `subject` differ per route. */
|
|
16
|
-
interface AccountClaimBase {
|
|
17
|
-
/** The namespace, hex: the id `foundNamespace` returned. */
|
|
18
|
-
namespaceId: string;
|
|
19
|
-
/** The founding account, hex. */
|
|
20
|
-
accountId: string;
|
|
21
|
-
/** The salt `foundNamespace` returned, hex (32 bytes). */
|
|
22
|
-
salt: string;
|
|
23
|
-
/** The account's credential, hex `AccountProof<DeviceCert>`. */
|
|
24
|
-
credential: string;
|
|
25
|
-
deviceSecret?: string;
|
|
26
|
-
signer?: Signer;
|
|
27
|
-
/** Lifetime in ms; default one minute, at most five. */
|
|
28
|
-
ttlMs?: number;
|
|
29
|
-
/** For tests. */
|
|
30
|
-
now?: () => number;
|
|
31
|
-
}
|
|
32
|
-
export interface AccountOwnershipClaimInput extends AccountClaimBase {
|
|
33
|
-
/** The cloud login's email: the claim is for this login only. */
|
|
34
|
-
subject: string;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Input for {@link signAccountHaClaim}: the same as the session claim, minus
|
|
38
|
-
* `subject` — there is no login to bind it to.
|
|
39
|
-
*/
|
|
40
|
-
export interface AccountHaClaimInput extends AccountClaimBase {
|
|
41
|
-
/**
|
|
42
|
-
* The relay that founded the namespace (the delegated session's `relayUrl`).
|
|
43
|
-
* Signed into the claim so nobody forwarding it can swap it: the cloud
|
|
44
|
-
* resolves it to one of its own fleet relays and hands that relay's
|
|
45
|
-
* addresses to the fleet node as its admitter. Leave it out when unknown.
|
|
46
|
-
*/
|
|
47
|
-
relayUrl?: string;
|
|
48
|
-
}
|
|
49
|
-
/** The audience of the session route's claim (`/api/cloud/me/...`). */
|
|
50
|
-
export declare const ACCOUNT_OWNERSHIP_AUDIENCE = "mdma:enable-ha-namespace";
|
|
51
|
-
/** The audience of the anonymous account route's claim (`/api/cloud/accounts/...`). */
|
|
52
|
-
export declare const ACCOUNT_HA_AUDIENCE = "mdma:enable-ha-namespace-as-account";
|
|
53
|
-
/** The founder's claim for the SESSION route, bound to one cloud login (`subject`). */
|
|
54
|
-
export declare function signAccountOwnershipClaim(input: AccountOwnershipClaimInput): Promise<AccountOwnershipProof>;
|
|
55
|
-
/**
|
|
56
|
-
* The founder's claim for the ANONYMOUS account route
|
|
57
|
-
* (`POST /api/cloud/accounts/{account}/namespaces/{ns}/enable-ha`): no cloud
|
|
58
|
-
* session, so no `subject`, and its own audience so a claim minted for one
|
|
59
|
-
* route can never be replayed on the other. The cloud finds the user to bill
|
|
60
|
-
* through the account's wallet link instead.
|
|
61
|
-
*/
|
|
62
|
-
export declare function signAccountHaClaim(input: AccountHaClaimInput): Promise<AccountOwnershipProof>;
|
|
63
|
-
export {};
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The ownership claim an account with no node presents to enable HA for a
|
|
3
|
-
* namespace it founded through a relay (mdma#415).
|
|
4
|
-
*
|
|
5
|
-
* A node proves ownership with a proof signed by the namespace's group key,
|
|
6
|
-
* which a nodeless account does not hold. The account instead proves it is the
|
|
7
|
-
* FOUNDER: a namespace id is `domain_hash("calimero.namespace.id.v1",
|
|
8
|
-
* [founder_account, salt])`, so only the founding account, with the salt its
|
|
9
|
-
* founding returned, reproduces it. Its device key signs the claim, and its
|
|
10
|
-
* certificate says whose device that is. The cloud also requires the login to
|
|
11
|
-
* be linked to that account.
|
|
12
|
-
*
|
|
13
|
-
* Signature input: `"calimero.mdma.account-ownership-claim.v1\0" ‖ payload`,
|
|
14
|
-
* where `payload` is the UTF-8 JSON sent (base64) as `signed_payload`.
|
|
15
|
-
*/
|
|
16
|
-
import { concat } from '../crypto/internal.js';
|
|
17
|
-
import { resolveSigner } from '../signer/signer.js';
|
|
18
|
-
const DOMAIN = new TextEncoder().encode('calimero.mdma.account-ownership-claim.v1\0');
|
|
19
|
-
/** What the cloud accepts; it caps a claim's lifetime at five minutes. */
|
|
20
|
-
const DEFAULT_TTL_MS = 60000;
|
|
21
|
-
const MAX_TTL_MS = 5 * 60000;
|
|
22
|
-
/** The cloud's limit on `relay_url`. */
|
|
23
|
-
const MAX_RELAY_URL = 1024;
|
|
24
|
-
/** The audience of the session route's claim (`/api/cloud/me/...`). */
|
|
25
|
-
export const ACCOUNT_OWNERSHIP_AUDIENCE = 'mdma:enable-ha-namespace';
|
|
26
|
-
/** The audience of the anonymous account route's claim (`/api/cloud/accounts/...`). */
|
|
27
|
-
export const ACCOUNT_HA_AUDIENCE = 'mdma:enable-ha-namespace-as-account';
|
|
28
|
-
function base64(bytes) {
|
|
29
|
-
let binary = '';
|
|
30
|
-
for (const b of bytes)
|
|
31
|
-
binary += String.fromCharCode(b);
|
|
32
|
-
return btoa(binary);
|
|
33
|
-
}
|
|
34
|
-
const hex32 = (value, what) => {
|
|
35
|
-
if (!/^[0-9a-fA-F]{64}$/.test(value))
|
|
36
|
-
throw new Error(`${what} must be 64 hex characters`);
|
|
37
|
-
return value.toLowerCase();
|
|
38
|
-
};
|
|
39
|
-
/**
|
|
40
|
-
* Sign one claim. `subject` is spliced in after `salt` only when given, so the
|
|
41
|
-
* session claim keeps its exact field order and the account claim has no
|
|
42
|
-
* `subject` key at all (not a null one: the cloud tells the two apart by it).
|
|
43
|
-
*/
|
|
44
|
-
async function signClaim(input, audience, subject, relayUrl) {
|
|
45
|
-
if (relayUrl !== undefined && !(relayUrl.length > 0 && relayUrl.length <= MAX_RELAY_URL)) {
|
|
46
|
-
throw new Error(`relayUrl must be a non-empty string of at most ${MAX_RELAY_URL} characters`);
|
|
47
|
-
}
|
|
48
|
-
const ttl = input.ttlMs ?? DEFAULT_TTL_MS;
|
|
49
|
-
if (!(ttl > 0 && ttl <= MAX_TTL_MS))
|
|
50
|
-
throw new Error(`ttlMs must be in (0, ${MAX_TTL_MS}]`);
|
|
51
|
-
const groupId = hex32(input.namespaceId, 'namespaceId');
|
|
52
|
-
const accountId = hex32(input.accountId, 'accountId');
|
|
53
|
-
const salt = hex32(input.salt, 'salt');
|
|
54
|
-
const signer = await resolveSigner(input.deviceSecret, input.signer, 'deviceSecret');
|
|
55
|
-
const issued = (input.now ?? Date.now)();
|
|
56
|
-
const nonce = Array.from(crypto.getRandomValues(new Uint8Array(16)), (b) => b.toString(16).padStart(2, '0')).join('');
|
|
57
|
-
const payload = new TextEncoder().encode(JSON.stringify({
|
|
58
|
-
v: 1,
|
|
59
|
-
audience,
|
|
60
|
-
group_id: groupId,
|
|
61
|
-
account_id: accountId,
|
|
62
|
-
salt,
|
|
63
|
-
...(subject === undefined ? {} : { subject }),
|
|
64
|
-
nonce,
|
|
65
|
-
issued_at_ms: issued,
|
|
66
|
-
expires_at_ms: issued + ttl,
|
|
67
|
-
...(relayUrl === undefined ? {} : { relay_url: relayUrl }),
|
|
68
|
-
}));
|
|
69
|
-
const signature = await signer.sign(concat(DOMAIN, payload));
|
|
70
|
-
return { kind: 'account', credential: input.credential, signed_payload: base64(payload), signature: base64(signature) };
|
|
71
|
-
}
|
|
72
|
-
/** The founder's claim for the SESSION route, bound to one cloud login (`subject`). */
|
|
73
|
-
export async function signAccountOwnershipClaim(input) {
|
|
74
|
-
if (!input.subject)
|
|
75
|
-
throw new Error('subject must be the cloud login email');
|
|
76
|
-
return signClaim(input, ACCOUNT_OWNERSHIP_AUDIENCE, input.subject);
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* The founder's claim for the ANONYMOUS account route
|
|
80
|
-
* (`POST /api/cloud/accounts/{account}/namespaces/{ns}/enable-ha`): no cloud
|
|
81
|
-
* session, so no `subject`, and its own audience so a claim minted for one
|
|
82
|
-
* route can never be replayed on the other. The cloud finds the user to bill
|
|
83
|
-
* through the account's wallet link instead.
|
|
84
|
-
*/
|
|
85
|
-
export async function signAccountHaClaim(input) {
|
|
86
|
-
return signClaim(input, ACCOUNT_HA_AUDIENCE, undefined, input.relayUrl);
|
|
87
|
-
}
|