@spfn/auth 0.2.0-beta.87 → 0.2.0-beta.89
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 +384 -18
- package/dist/{authenticate-C7w-pLOR.d.ts → authenticate-DK-hLSOW.d.ts} +154 -5
- package/dist/client-proof.d.ts +122 -2
- package/dist/client-proof.js +366 -5
- package/dist/client-proof.js.map +1 -1
- package/dist/config.d.ts +36 -0
- package/dist/config.js +18 -0
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +93 -2
- package/dist/errors.js +57 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +32 -3
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -1
- package/dist/nextjs/server.d.ts +2 -2
- package/dist/server.d.ts +126 -11
- package/dist/server.js +527 -106
- package/dist/server.js.map +1 -1
- package/dist/{session-CGxgH3C9.d.ts → session-CFK4BT25.d.ts} +1 -1
- package/dist/{types-1BMx0OX1.d.ts → types-CD95yudz.d.ts} +15 -1
- package/migrations/20251125021229_premium_famine/snapshot.json +2641 -0
- package/migrations/20260225130050_smooth_the_fury/snapshot.json +2686 -0
- package/migrations/20260308141417_deep_iceman/snapshot.json +2686 -0
- package/migrations/20260308151309_perfect_deathbird/snapshot.json +2731 -0
- package/migrations/20260308201135_concerned_rawhide_kid/snapshot.json +2786 -0
- package/migrations/20260629103209_lethal_lifeguard/snapshot.json +2786 -0
- package/migrations/20260709073531_easy_hardball/snapshot.json +3119 -0
- package/migrations/20260714081434_glossy_major_mapleleaf/snapshot.json +3112 -0
- package/migrations/20260804105939_amazing_bushwacker/migration.sql +3 -0
- package/migrations/20260804105939_amazing_bushwacker/snapshot.json +3112 -0
- package/migrations/20260804110033_fat_piledriver/migration.sql +2 -0
- package/migrations/20260804110033_fat_piledriver/snapshot.json +3138 -0
- package/package.json +3 -6
- package/migrations/meta/0000_snapshot.json +0 -1632
- package/migrations/meta/0001_snapshot.json +0 -1660
- package/migrations/meta/0002_snapshot.json +0 -1660
- package/migrations/meta/0003_snapshot.json +0 -1689
- package/migrations/meta/0004_snapshot.json +0 -1721
- package/migrations/meta/0005_snapshot.json +0 -1721
- package/migrations/meta/0006_snapshot.json +0 -1921
- package/migrations/meta/0007_snapshot.json +0 -1916
- package/migrations/meta/_journal.json +0 -62
- /package/migrations/{0000_premium_famine.sql → 20251125021229_premium_famine/migration.sql} +0 -0
- /package/migrations/{0001_smooth_the_fury.sql → 20260225130050_smooth_the_fury/migration.sql} +0 -0
- /package/migrations/{0002_deep_iceman.sql → 20260308141417_deep_iceman/migration.sql} +0 -0
- /package/migrations/{0003_perfect_deathbird.sql → 20260308151309_perfect_deathbird/migration.sql} +0 -0
- /package/migrations/{0004_concerned_rawhide_kid.sql → 20260308201135_concerned_rawhide_kid/migration.sql} +0 -0
- /package/migrations/{0005_lethal_lifeguard.sql → 20260629103209_lethal_lifeguard/migration.sql} +0 -0
- /package/migrations/{0006_easy_hardball.sql → 20260709073531_easy_hardball/migration.sql} +0 -0
- /package/migrations/{0007_glossy_major_mapleleaf.sql → 20260714081434_glossy_major_mapleleaf/migration.sql} +0 -0
package/dist/client-proof.js
CHANGED
|
@@ -496,6 +496,18 @@ var ClientProofRefusal = class _ClientProofRefusal {
|
|
|
496
496
|
static unprocessable() {
|
|
497
497
|
return contractViolation("the request could not be processed");
|
|
498
498
|
}
|
|
499
|
+
/**
|
|
500
|
+
* A client that ships separately from the server said nothing about which
|
|
501
|
+
* contract it was built against. Without it the server cannot tell whether
|
|
502
|
+
* the two ends agree, and answering as though they do is what produces the
|
|
503
|
+
* undecodable body this check exists to replace.
|
|
504
|
+
*/
|
|
505
|
+
static contractVersionMissing() {
|
|
506
|
+
return contractViolation("a client of this kind must state the contract version it was generated from");
|
|
507
|
+
}
|
|
508
|
+
static contractVersionUnsupported() {
|
|
509
|
+
return contractViolation("the stated contract version is outside the range this server serves");
|
|
510
|
+
}
|
|
499
511
|
// ---- the profile allowlist ----------------------------------------------
|
|
500
512
|
static profileRejected() {
|
|
501
513
|
return new _ClientProofRefusal("PROFILE_REJECTED", "the named auth profile is not on this contract's allowlist");
|
|
@@ -983,6 +995,36 @@ var AUTH_SURFACE_OPERATIONS = [
|
|
|
983
995
|
requestType: "RotateKeyRequest",
|
|
984
996
|
responseType: "RotateKeyResponse",
|
|
985
997
|
summary: "Replaces the authenticated key with a new client-generated public key before its TTL runs out."
|
|
998
|
+
},
|
|
999
|
+
{
|
|
1000
|
+
id: "auth.keys.list",
|
|
1001
|
+
method: "POST",
|
|
1002
|
+
path: "/_auth/keys/list",
|
|
1003
|
+
authProfile: "clientProofV1",
|
|
1004
|
+
requiresSession: false,
|
|
1005
|
+
requestType: "ListKeysRequest",
|
|
1006
|
+
responseType: "ListKeysResponse",
|
|
1007
|
+
summary: "Lists the keys registered to the caller, one per device that can sign for them."
|
|
1008
|
+
},
|
|
1009
|
+
{
|
|
1010
|
+
id: "auth.keys.revoke",
|
|
1011
|
+
method: "POST",
|
|
1012
|
+
path: "/_auth/keys/revoke",
|
|
1013
|
+
authProfile: "clientProofV1",
|
|
1014
|
+
requiresSession: false,
|
|
1015
|
+
requestType: "RevokeKeyRequest",
|
|
1016
|
+
responseType: "RevokeKeyResponse",
|
|
1017
|
+
summary: "Revokes one of the caller's keys, signing that device out."
|
|
1018
|
+
},
|
|
1019
|
+
{
|
|
1020
|
+
id: "auth.keys.revokeAll",
|
|
1021
|
+
method: "POST",
|
|
1022
|
+
path: "/_auth/keys/revoke-all",
|
|
1023
|
+
authProfile: "clientProofV1",
|
|
1024
|
+
requiresSession: false,
|
|
1025
|
+
requestType: "RevokeAllKeysRequest",
|
|
1026
|
+
responseType: "RevokeAllKeysResponse",
|
|
1027
|
+
summary: "Revokes every key the caller has, sparing the calling device unless asked otherwise."
|
|
986
1028
|
}
|
|
987
1029
|
];
|
|
988
1030
|
var ContractTypeError = class extends Error {
|
|
@@ -1015,17 +1057,17 @@ function decodeListItemsRequest(value) {
|
|
|
1015
1057
|
}
|
|
1016
1058
|
return request;
|
|
1017
1059
|
}
|
|
1018
|
-
function objectWithKeys(value,
|
|
1060
|
+
function objectWithKeys(value, required2, optional2) {
|
|
1019
1061
|
if (!(value instanceof Map)) {
|
|
1020
1062
|
throw new ContractTypeError();
|
|
1021
1063
|
}
|
|
1022
|
-
for (const key of
|
|
1064
|
+
for (const key of required2) {
|
|
1023
1065
|
if (!value.has(key)) {
|
|
1024
1066
|
throw new ContractTypeError();
|
|
1025
1067
|
}
|
|
1026
1068
|
}
|
|
1027
1069
|
for (const key of value.keys()) {
|
|
1028
|
-
if (!
|
|
1070
|
+
if (!required2.includes(key) && !optional2.includes(key)) {
|
|
1029
1071
|
throw new ContractTypeError();
|
|
1030
1072
|
}
|
|
1031
1073
|
}
|
|
@@ -1221,6 +1263,289 @@ function answer(status, value) {
|
|
|
1221
1263
|
return new Response(buffer, { status, headers: { "content-type": "application/json" } });
|
|
1222
1264
|
}
|
|
1223
1265
|
|
|
1266
|
+
// src/server/client-proof/contract-bundle.ts
|
|
1267
|
+
import { createHash as createHash2 } from "crypto";
|
|
1268
|
+
|
|
1269
|
+
// src/server/types.ts
|
|
1270
|
+
var KEY_ALGORITHM = ["ES256", "RS256"];
|
|
1271
|
+
|
|
1272
|
+
// src/server/client-proof/wire-headers.ts
|
|
1273
|
+
var CLIENT_IDENTITY_HEADERS = {
|
|
1274
|
+
kind: "x-spfn-client-kind",
|
|
1275
|
+
version: "x-spfn-client-version",
|
|
1276
|
+
contractVersion: "x-spfn-client-contract-version"
|
|
1277
|
+
};
|
|
1278
|
+
var SERVER_CONTRACT_HEADERS = {
|
|
1279
|
+
version: "x-spfn-server-contract-version",
|
|
1280
|
+
supportedRange: "x-spfn-supported-contract-range"
|
|
1281
|
+
};
|
|
1282
|
+
var CLIENT_KINDS = ["web", "ios", "android"];
|
|
1283
|
+
function isAppKind(kind) {
|
|
1284
|
+
return kind !== "web";
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
// src/server/client-proof/contract-bundle.ts
|
|
1288
|
+
var CONTRACT_VERSION = "0.6.0";
|
|
1289
|
+
var CONTRACT_MAJOR = 0;
|
|
1290
|
+
var CONTRACT_SUPPORTED_RANGE = ">=0.6.0 <0.7.0";
|
|
1291
|
+
function required(name, type) {
|
|
1292
|
+
return { name, type, optional: false };
|
|
1293
|
+
}
|
|
1294
|
+
function optional(name, type) {
|
|
1295
|
+
return { name, type, optional: true };
|
|
1296
|
+
}
|
|
1297
|
+
var CONTRACT_TYPES = [
|
|
1298
|
+
{
|
|
1299
|
+
name: "HandshakeRequest",
|
|
1300
|
+
fields: [
|
|
1301
|
+
required("clientId", "string"),
|
|
1302
|
+
required("keyId", "string"),
|
|
1303
|
+
required("nonce", "string"),
|
|
1304
|
+
required("issuedAtMillis", "integer")
|
|
1305
|
+
]
|
|
1306
|
+
},
|
|
1307
|
+
{
|
|
1308
|
+
name: "HandshakeResponse",
|
|
1309
|
+
fields: [
|
|
1310
|
+
required("sessionId", "string"),
|
|
1311
|
+
required("expiresAtMillis", "integer")
|
|
1312
|
+
]
|
|
1313
|
+
},
|
|
1314
|
+
{
|
|
1315
|
+
name: "EchoRequest",
|
|
1316
|
+
fields: [
|
|
1317
|
+
required("message", "string"),
|
|
1318
|
+
required("sequence", "integer")
|
|
1319
|
+
]
|
|
1320
|
+
},
|
|
1321
|
+
{
|
|
1322
|
+
name: "EchoResponse",
|
|
1323
|
+
fields: [
|
|
1324
|
+
required("message", "string"),
|
|
1325
|
+
required("sequence", "integer"),
|
|
1326
|
+
required("serverTimeMillis", "integer")
|
|
1327
|
+
]
|
|
1328
|
+
},
|
|
1329
|
+
{
|
|
1330
|
+
name: "ListItemsRequest",
|
|
1331
|
+
fields: [
|
|
1332
|
+
required("limit", "integer"),
|
|
1333
|
+
optional("cursor", "string")
|
|
1334
|
+
]
|
|
1335
|
+
},
|
|
1336
|
+
{
|
|
1337
|
+
name: "Item",
|
|
1338
|
+
fields: [
|
|
1339
|
+
required("id", "string"),
|
|
1340
|
+
required("name", "string"),
|
|
1341
|
+
required("updatedAtMillis", "integer")
|
|
1342
|
+
]
|
|
1343
|
+
},
|
|
1344
|
+
{
|
|
1345
|
+
name: "ListItemsResponse",
|
|
1346
|
+
fields: [
|
|
1347
|
+
required("items", "array<Item>"),
|
|
1348
|
+
optional("nextCursor", "string")
|
|
1349
|
+
]
|
|
1350
|
+
},
|
|
1351
|
+
{
|
|
1352
|
+
name: "RegisterRequest",
|
|
1353
|
+
fields: [
|
|
1354
|
+
optional("email", "string"),
|
|
1355
|
+
optional("phone", "string"),
|
|
1356
|
+
required("verificationToken", "string"),
|
|
1357
|
+
required("password", "string"),
|
|
1358
|
+
required("publicKey", "string"),
|
|
1359
|
+
required("keyId", "string"),
|
|
1360
|
+
required("fingerprint", "string"),
|
|
1361
|
+
required("algorithm", "KeyAlgorithm")
|
|
1362
|
+
]
|
|
1363
|
+
},
|
|
1364
|
+
{
|
|
1365
|
+
name: "RegisterResponse",
|
|
1366
|
+
fields: [
|
|
1367
|
+
required("userId", "string"),
|
|
1368
|
+
required("publicId", "string"),
|
|
1369
|
+
optional("email", "string"),
|
|
1370
|
+
optional("phone", "string")
|
|
1371
|
+
]
|
|
1372
|
+
},
|
|
1373
|
+
{
|
|
1374
|
+
name: "LoginRequest",
|
|
1375
|
+
fields: [
|
|
1376
|
+
optional("email", "string"),
|
|
1377
|
+
optional("phone", "string"),
|
|
1378
|
+
required("password", "string"),
|
|
1379
|
+
required("publicKey", "string"),
|
|
1380
|
+
required("keyId", "string"),
|
|
1381
|
+
required("fingerprint", "string"),
|
|
1382
|
+
required("algorithm", "KeyAlgorithm"),
|
|
1383
|
+
optional("oldKeyId", "string")
|
|
1384
|
+
]
|
|
1385
|
+
},
|
|
1386
|
+
{
|
|
1387
|
+
name: "LoginResponse",
|
|
1388
|
+
fields: [
|
|
1389
|
+
required("userId", "string"),
|
|
1390
|
+
required("publicId", "string"),
|
|
1391
|
+
optional("email", "string"),
|
|
1392
|
+
optional("phone", "string"),
|
|
1393
|
+
required("passwordChangeRequired", "boolean")
|
|
1394
|
+
]
|
|
1395
|
+
},
|
|
1396
|
+
{
|
|
1397
|
+
name: "OauthNativeRequest",
|
|
1398
|
+
fields: [
|
|
1399
|
+
required("idToken", "string"),
|
|
1400
|
+
required("nonce", "string"),
|
|
1401
|
+
optional("accessToken", "string"),
|
|
1402
|
+
required("publicKey", "string"),
|
|
1403
|
+
required("keyId", "string"),
|
|
1404
|
+
required("fingerprint", "string"),
|
|
1405
|
+
required("algorithm", "KeyAlgorithm")
|
|
1406
|
+
]
|
|
1407
|
+
},
|
|
1408
|
+
{
|
|
1409
|
+
name: "OauthNativeResponse",
|
|
1410
|
+
fields: [
|
|
1411
|
+
required("userId", "string"),
|
|
1412
|
+
required("keyId", "string"),
|
|
1413
|
+
required("isNewUser", "boolean")
|
|
1414
|
+
]
|
|
1415
|
+
},
|
|
1416
|
+
{
|
|
1417
|
+
name: "RotateKeyRequest",
|
|
1418
|
+
fields: [
|
|
1419
|
+
required("publicKey", "string"),
|
|
1420
|
+
required("keyId", "string"),
|
|
1421
|
+
required("fingerprint", "string"),
|
|
1422
|
+
required("algorithm", "KeyAlgorithm")
|
|
1423
|
+
]
|
|
1424
|
+
},
|
|
1425
|
+
{
|
|
1426
|
+
name: "RotateKeyResponse",
|
|
1427
|
+
fields: [
|
|
1428
|
+
required("success", "boolean"),
|
|
1429
|
+
required("keyId", "string")
|
|
1430
|
+
]
|
|
1431
|
+
},
|
|
1432
|
+
{
|
|
1433
|
+
name: "ListKeysRequest",
|
|
1434
|
+
fields: [
|
|
1435
|
+
optional("includeRevoked", "boolean")
|
|
1436
|
+
]
|
|
1437
|
+
},
|
|
1438
|
+
{
|
|
1439
|
+
name: "KeySummary",
|
|
1440
|
+
fields: [
|
|
1441
|
+
required("keyId", "string"),
|
|
1442
|
+
optional("deviceName", "string"),
|
|
1443
|
+
optional("platform", "string"),
|
|
1444
|
+
required("algorithm", "KeyAlgorithm"),
|
|
1445
|
+
required("fingerprintPrefix", "string"),
|
|
1446
|
+
required("createdAtMillis", "integer"),
|
|
1447
|
+
optional("lastUsedAtMillis", "integer"),
|
|
1448
|
+
optional("expiresAtMillis", "integer"),
|
|
1449
|
+
required("isExpired", "boolean"),
|
|
1450
|
+
required("isActive", "boolean"),
|
|
1451
|
+
optional("revokedAtMillis", "integer")
|
|
1452
|
+
]
|
|
1453
|
+
},
|
|
1454
|
+
{
|
|
1455
|
+
name: "ListKeysResponse",
|
|
1456
|
+
fields: [
|
|
1457
|
+
required("keys", "array<KeySummary>")
|
|
1458
|
+
]
|
|
1459
|
+
},
|
|
1460
|
+
{
|
|
1461
|
+
name: "RevokeKeyRequest",
|
|
1462
|
+
fields: [
|
|
1463
|
+
required("keyId", "string")
|
|
1464
|
+
]
|
|
1465
|
+
},
|
|
1466
|
+
{
|
|
1467
|
+
name: "RevokeKeyResponse",
|
|
1468
|
+
fields: [
|
|
1469
|
+
required("keyId", "string"),
|
|
1470
|
+
required("selfRevoked", "boolean")
|
|
1471
|
+
]
|
|
1472
|
+
},
|
|
1473
|
+
{
|
|
1474
|
+
name: "RevokeAllKeysRequest",
|
|
1475
|
+
fields: [
|
|
1476
|
+
optional("includeCurrent", "boolean")
|
|
1477
|
+
]
|
|
1478
|
+
},
|
|
1479
|
+
{
|
|
1480
|
+
name: "RevokeAllKeysResponse",
|
|
1481
|
+
fields: [
|
|
1482
|
+
required("revokedCount", "integer"),
|
|
1483
|
+
required("currentKeyRevoked", "boolean")
|
|
1484
|
+
]
|
|
1485
|
+
}
|
|
1486
|
+
];
|
|
1487
|
+
var CONTRACT_ENUMS = [
|
|
1488
|
+
{ name: "KeyAlgorithm", values: [...KEY_ALGORITHM] }
|
|
1489
|
+
];
|
|
1490
|
+
var BUNDLE_FILENAME = "spfn-mobile-contract.json";
|
|
1491
|
+
var BUNDLE_REPO_PATH = `contracts/mobile/${BUNDLE_FILENAME}`;
|
|
1492
|
+
|
|
1493
|
+
// src/server/client-proof/wire-version.ts
|
|
1494
|
+
function readClientIdentity(headers) {
|
|
1495
|
+
const kind = headers.get(CLIENT_IDENTITY_HEADERS.kind);
|
|
1496
|
+
if (kind === null || !isClientKind(kind)) {
|
|
1497
|
+
return null;
|
|
1498
|
+
}
|
|
1499
|
+
return {
|
|
1500
|
+
kind,
|
|
1501
|
+
version: headers.get(CLIENT_IDENTITY_HEADERS.version),
|
|
1502
|
+
contractVersion: headers.get(CLIENT_IDENTITY_HEADERS.contractVersion)
|
|
1503
|
+
};
|
|
1504
|
+
}
|
|
1505
|
+
function isClientKind(value) {
|
|
1506
|
+
return CLIENT_KINDS.includes(value);
|
|
1507
|
+
}
|
|
1508
|
+
function isContractVersionSupported(clientVersion) {
|
|
1509
|
+
const client = parseVersion(clientVersion);
|
|
1510
|
+
if (client === null) {
|
|
1511
|
+
return false;
|
|
1512
|
+
}
|
|
1513
|
+
const server = parseVersion(CONTRACT_VERSION);
|
|
1514
|
+
if (server === null || client.major !== server.major) {
|
|
1515
|
+
return false;
|
|
1516
|
+
}
|
|
1517
|
+
return CONTRACT_MAJOR > 0 || client.minor === server.minor;
|
|
1518
|
+
}
|
|
1519
|
+
function parseVersion(raw) {
|
|
1520
|
+
const match = /^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/.exec(raw);
|
|
1521
|
+
if (match === null) {
|
|
1522
|
+
return null;
|
|
1523
|
+
}
|
|
1524
|
+
return { major: Number(match[1]), minor: Number(match[2]) };
|
|
1525
|
+
}
|
|
1526
|
+
function judgeClientIdentity(identity) {
|
|
1527
|
+
if (identity === null || !isAppKind(identity.kind)) {
|
|
1528
|
+
return null;
|
|
1529
|
+
}
|
|
1530
|
+
if (identity.contractVersion === null) {
|
|
1531
|
+
return ClientProofRefusal.contractVersionMissing();
|
|
1532
|
+
}
|
|
1533
|
+
if (!isContractVersionSupported(identity.contractVersion)) {
|
|
1534
|
+
return ClientProofRefusal.contractVersionUnsupported();
|
|
1535
|
+
}
|
|
1536
|
+
return null;
|
|
1537
|
+
}
|
|
1538
|
+
function applyServerContractHeaders(headers) {
|
|
1539
|
+
headers.set(SERVER_CONTRACT_HEADERS.version, CONTRACT_VERSION);
|
|
1540
|
+
headers.set(SERVER_CONTRACT_HEADERS.supportedRange, CONTRACT_SUPPORTED_RANGE);
|
|
1541
|
+
}
|
|
1542
|
+
function serverContractHeaders() {
|
|
1543
|
+
return {
|
|
1544
|
+
[SERVER_CONTRACT_HEADERS.version]: CONTRACT_VERSION,
|
|
1545
|
+
[SERVER_CONTRACT_HEADERS.supportedRange]: CONTRACT_SUPPORTED_RANGE
|
|
1546
|
+
};
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1224
1549
|
// src/server/client-proof/dev-handler.ts
|
|
1225
1550
|
var MAX_BODY_BYTES = 1 << 20;
|
|
1226
1551
|
var HTTP_OK2 = 200;
|
|
@@ -1338,7 +1663,7 @@ function listItems(request) {
|
|
|
1338
1663
|
function contractResponse(status, body) {
|
|
1339
1664
|
return new Response(toArrayBuffer(body), {
|
|
1340
1665
|
status,
|
|
1341
|
-
headers: { "content-type": "application/json" }
|
|
1666
|
+
headers: { "content-type": "application/json", ...serverContractHeaders() }
|
|
1342
1667
|
});
|
|
1343
1668
|
}
|
|
1344
1669
|
async function readBodyCapped(request) {
|
|
@@ -1389,7 +1714,8 @@ function createClientProofGuard(state, options = {}) {
|
|
|
1389
1714
|
const bytes = admission.refusal.envelopeBytes(newHexId());
|
|
1390
1715
|
const buffer = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
|
|
1391
1716
|
return c.newResponse(buffer, admission.refusal.httpStatus, {
|
|
1392
|
-
"content-type": "application/json"
|
|
1717
|
+
"content-type": "application/json",
|
|
1718
|
+
...serverContractHeaders()
|
|
1393
1719
|
});
|
|
1394
1720
|
}
|
|
1395
1721
|
c.set("clientType", "mobile");
|
|
@@ -1401,9 +1727,36 @@ function createClientProofGuard(state, options = {}) {
|
|
|
1401
1727
|
return void 0;
|
|
1402
1728
|
};
|
|
1403
1729
|
}
|
|
1730
|
+
|
|
1731
|
+
// src/server/client-proof/version-middleware.ts
|
|
1732
|
+
var CLIENT_IDENTITY_CONTEXT_KEY = "clientIdentity";
|
|
1733
|
+
function createClientVersionMiddleware() {
|
|
1734
|
+
return async (c, next) => {
|
|
1735
|
+
const identity = readClientIdentity(c.req.raw.headers);
|
|
1736
|
+
const refusal = judgeClientIdentity(identity);
|
|
1737
|
+
if (refusal !== null) {
|
|
1738
|
+
const bytes = refusal.envelopeBytes(newHexId());
|
|
1739
|
+
const buffer = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
|
|
1740
|
+
const response = c.newResponse(buffer, refusal.httpStatus, {
|
|
1741
|
+
"content-type": "application/json"
|
|
1742
|
+
});
|
|
1743
|
+
applyServerContractHeaders(response.headers);
|
|
1744
|
+
return response;
|
|
1745
|
+
}
|
|
1746
|
+
if (identity !== null) {
|
|
1747
|
+
c.set(CLIENT_IDENTITY_CONTEXT_KEY, identity);
|
|
1748
|
+
}
|
|
1749
|
+
await next();
|
|
1750
|
+
applyServerContractHeaders(c.res.headers);
|
|
1751
|
+
return void 0;
|
|
1752
|
+
};
|
|
1753
|
+
}
|
|
1404
1754
|
export {
|
|
1405
1755
|
ABSENT_BODY_SHA256,
|
|
1406
1756
|
AUTH_SURFACE_OPERATIONS,
|
|
1757
|
+
CLIENT_IDENTITY_CONTEXT_KEY,
|
|
1758
|
+
CLIENT_IDENTITY_HEADERS,
|
|
1759
|
+
CLIENT_KINDS,
|
|
1407
1760
|
CLIENT_PROOF_CONTENT_TYPE,
|
|
1408
1761
|
CLIENT_PROOF_HEADERS,
|
|
1409
1762
|
CLIENT_PROOF_PROFILE,
|
|
@@ -1424,12 +1777,15 @@ export {
|
|
|
1424
1777
|
PROOF_SIGNATURE_HEX_LENGTH,
|
|
1425
1778
|
ProofInputError,
|
|
1426
1779
|
RedisReplayStore,
|
|
1780
|
+
SERVER_CONTRACT_HEADERS,
|
|
1427
1781
|
TestClock,
|
|
1428
1782
|
admitClientProofRequest,
|
|
1783
|
+
applyServerContractHeaders,
|
|
1429
1784
|
canonicalProofInput,
|
|
1430
1785
|
configureClientProofReplayStore,
|
|
1431
1786
|
createClientProofDevHandler,
|
|
1432
1787
|
createClientProofGuard,
|
|
1788
|
+
createClientVersionMiddleware,
|
|
1433
1789
|
decodeEchoRequest,
|
|
1434
1790
|
decodeHandshakeRequest,
|
|
1435
1791
|
decodeListItemsRequest,
|
|
@@ -1438,13 +1794,18 @@ export {
|
|
|
1438
1794
|
encodeHandshakeResponse,
|
|
1439
1795
|
encodeListItemsResponse,
|
|
1440
1796
|
getClientProofReplayStore,
|
|
1797
|
+
isAppKind,
|
|
1441
1798
|
isCanonicalBytes,
|
|
1799
|
+
isContractVersionSupported,
|
|
1442
1800
|
isRequestContentType,
|
|
1801
|
+
judgeClientIdentity,
|
|
1443
1802
|
newHexId,
|
|
1444
1803
|
parseCanonicalJson,
|
|
1445
1804
|
parseClientProofPublicKey,
|
|
1805
|
+
readClientIdentity,
|
|
1446
1806
|
readCredentials,
|
|
1447
1807
|
replayLedgerKey,
|
|
1808
|
+
serverContractHeaders,
|
|
1448
1809
|
sha256Hex,
|
|
1449
1810
|
signClientProof,
|
|
1450
1811
|
systemClock,
|