@signalapp/mock-server
Advanced tools
Comparing version 7.0.2 to 7.1.0
@@ -10,2 +10,4 @@ 'use strict'; | ||
const genericPublicParams = genericSecretParams.getPublicParams(); | ||
const backupSecretParams = GenericServerSecretParams.generate(); | ||
const backupPublicParams = backupSecretParams.getPublicParams(); | ||
@@ -17,2 +19,4 @@ fs.writeFileSync(process.argv[2], JSON.stringify({ | ||
genericPublicParams: genericPublicParams.serialize().toString('base64'), | ||
backupSecretParams: backupSecretParams.serialize().toString('base64'), | ||
backupPublicParams: backupPublicParams.serialize().toString('base64'), | ||
}, null, 2)); |
{ | ||
"secretParams": "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", | ||
"publicParams": "AJDe7g7oQkqEQ49VC9kgsoYt4MYPX5vbdFcB5f5cQbtS4J2jT1D6LLeuALsoaStyMPRxzevM0lQNG8bwMFXoSGnglxGDgI9e157eOgENVDNZfXbiyUCOw1X/ANxIIyk4ePL4040+7vOLkkYAfrmgNUry4WMNHl9j8bYIH54jaexgCM+Wq2udlK9ox27gvVe2GqajGKnlhbWG2w6deNWR70m4OZb1Cb7pmxY1XCDxSl0R039mbmSnJ5qPsWHQpvMCUr5GISdtIouvlViUkoftAo0Ihg2Noyn1SryVW3niOd5egKNBn2GnI+xaKljIz8PlCVS715TcptVFqkEaHAJCRwyUYAW7ly8T0wdlNBzZBSsNHOvs4bM9X+IBkMHPF0wdZ2jFW6VuM64QZpF9Yxp814ekeJr9t9N/Dxytfuth1NJnYEXy0R3GupJKpYK7Gz14MIMlZBh5JUKX7YGhFSEth2ji3r5aZLl0AcsePb5vDFSRPk+Bshszh+rGcdka4wPuD3LHJr1eSoBEPPMd6WiN9EoH6+cFGrq0vmR4Rt0f8RAVOOsfFJb9418T+qI9VFHsErkJmjSB5YN7igRCarhG1VbYbZ5UmxtjEq/wy2/0FvPaLfscuvyfYpIsmqltiE/AfmYFk9tYJUSZqUoUT6a88roUK5UErGE1nhtMJsbj+kJbZivt5yEEpFszyRctg4AkOrpcUWijn5sd3YsmpXOzlQ6IoD6UTIETOtQRIU+8gZoV/J919KLd9w76BAGTbFEzcUSZslbJXjqS7A4Z7sjryaDFRpUq00C3msQABkY4XqZNeO7vdIZIMURAHNgDjGSHdv7myFYcev09UwmP82uiE2w21Ggas+Zsfrze307HUOFppdrlYMk7V2NAbOG97au2Hg==", | ||
"genericSecretParams": "AGhg0n6304wIwAqGhciVHfZuyGb8GgVwu+WhNXxucCUHxbw8mZUbiyRgI7B6DNhP3fkG8tTRrtM4E5+Ks8tGhAUsQUJCDzsk/tTr8QwqSpfzDNRWUgxW++TDUirKycBiRhYf0o41srwcrwtPn/8sjfT44s63bX2HNjWVZZFNIqsGG1+Kq4AEZ+nh+pX+1PCMbl3kPhwJT868sXtvv3aZ0A1cvpuxk1SbmEcq2uBe9TjVMjaI2edGSsu7//PZb0VLCdTjWWxXKwURNSw1GxcZBw2qB6vMlfjI7pnvzRlYClsBAA+lcj5j3INiFv7jRfU1UljTSZcVnWlVjlZCh6wqQwUvPZdVV2U8crni59Cbb8suUk3axGlfzxmch69qBskmAR1eEzN+JXvoiwXnjyEaI6JV6qlr4FCQ2iYyT3SrkOAP31aEqMYtVlTDr4ULavt/ks21wIDweH5JsVtS/+G2bgIaO4ZRvb+XNZcKBtJNjEy3E8e4R1hP7cnfAuppWeRXCg==", | ||
"genericPublicParams": "AECVlQS3SWJhGYfCwjClt7j152IXKTU34hmO3BvUtLoqLu+jpZz5cy2jQhZolDshs69FpKpZhwgjPsPvwd15+FDaP7AdQNAUwyLEjtPE88Z/XTN6CLzKqpDdXhx9muyQYsrtPtGqrDscRspE4w2aVsEAUlOeNoDKPf7UnQjBiwFDTC2I/kQV638NBY40q4HLXHx/uo1MOhVmUar5na6VzCcS63VUv8+zzUbt51jN/QW5UtQtQ2wTtOpemdAZHuyVO/7t6DOQ+vJUBvxFXdnS00c2u3mZqW0CilGcXkXfQ+pF" | ||
"secretParams": "AO+mldTEMQNCmAuOfmpEtB7SgGUTS+hjHS5fxuQTOakH8AgBJFAyly5hxxRq99J2gfclDWVUSILAcpVIEl61qQu0f36tHEmpQauCIlDQHZltasHCQCTP/UdoOUDq17w+bwVPDQPLdUD9zL7kV1HmTA3PHZDYQ1dMM2qtnlBtrqwAkIivfOkdpSjggzG6DUMksU3dMa80XyXKGu7Wkc23DQbegnpO4KX1bY/dRnrW9pdvq5s/fWUdSq4vuqgYdNv+C6W9Shirn8eDpw8eTtl3SHUFrNwHumPvnlPnioljmAILmg+8pz5JJH52yY+i7EvU9pe5G6nkB00Qo69lpoWfDAh7Cfjr9wL6AsX2GkaYisyWQQGo+0ZjFr4QkvvSC83TBSK6MI2KosIo/Ne0RZJByuVUKryZrCnvS1NBCKBqaEVMBK8WjHp29d0uqYTrW1YsU1zNEzA9nVVQoi2+dumkG2WxCIpoKZ8JSoKPoWxGo23VRgKAMmRW5VqCLYkassVHDSwQMfeN1RJXwg79LagzJOyeFwpPk2S1kpgHIj5+Z/oJSrWEik3Z2mvC69RlR43vrE0Qcg+wAOqQuGb/E6d9bRtbFQ/Fj/Qb5KqIbDW/rvAGikjkW05n/yloZkVcnrMgBGCmvejptBZkGW/AGnIqTPi6+Mkdmde+kU89Hx9ivhgGsJzYz6XPahVe8iU/w+g8kIP0lJKECR3xf+5tq/erngvNmeSJ/B5+LmC1Fal0LvfIodcg/CBfXDyeLEnOhgxuAFVAnpUKZqPWB5TenMTLWEtAvX+uc2HrZcu/ZXtZ2l8CBmW8dq8J6fAhB6HCx7szqEhjMsEAFyiQjfy2rMSQcgLMsW9pgMcG7c0Ms63XPauVr/QTKZZUqqehXtdckDGsYvIWVHoslT8CotrCdF5fkVFJMZLBEfPbWhxVjtBlEkcRH9RCCt9eenAEYZcS+ZMW+PZCKzjI9sbVionBLuowqgIODXul+3AQrRfP57ZLjZHwd+el+c/1ZXmJ+/InsF6/IHAlYxuvpn19fzaIJIZTHNdgnQ7dLalOhSaJV32ifoALIpk4JY6jjD3JZLYNlpvIzJx+T0RNZ5CmZrMMeMSnTgGMY5Nk2UtdbJV3gYyw2Ibmm9oxnXS1Ufo/IZjXrD7ecScsrtdQ4ByFZabRBrikm2Os7NGIvC8qE73QbjdvOOsEVWMPvF0qa978CTuBRwdjv64tUppCexyZTwgCfk/viA0ERhkA4GbVCP5GcRi/cIOBbIuUfUZgx4kCvCBRlDiGCVJ5oMg3+djc+Om23gQ7eZQdPeEk2/e/P4FsxLXCHjcL5LXYv/xYCjI+J2v8ZmLmXdszNHWlzT4QcpL6WYkaiAgmzxVyzphYvyyvBBJ0rchQyBgu3WLEOMM7qbC49RXZBHgdfCjrc/yBWWWaMOFYO4jnsXZ2vVP+1mcTv5PF654PmMPGNo3b5uATe4Z/bEK35Eb51P/WeTIWlmTTaNeP+2lsjCe4i0Qcvst4SitCF1YrBifIwQbNfUUwswvv+TCUCqWkcqO5hifj7JEmVGdVVU+OhjluRV3Ia0zTPHquJMUGQq222UZWqtnSoTXHPEBFGWHeBc/Wv8o9o4gOoYeTaAoYTQG7Jp5dV5Hu3of2eldYPR1dntYIfjurWwNx72w3BvDiOl+O069G4/oEyHyHU4FOPYDszmtpzhBTe5fD3/AOEbGZYBbZ9ckrtKaWHOSu1XkBMb9b54hIWfY5cIoFAQnyo4XMjuHXS8U22k9dPQn9Ddd6OUfyve4v7OSbKa/fCcvJvnshxp4sK1HSlOWJhAI2MphhX9bGyVgxTQpBe0AIjGeq7KOthm4kokBsNk9UuUlOcJFeJUuUxZv9IkqAlgEeFmFDechpob+HJDidjF5y8WB+JFO0oE/CFrv7FL2OAm5Lr19jtqotWrOhRHQ8AqyZYiW6luYtM11trKlqRcgOTJWFHuLw9GBo3RHxH8jQnPxEJHxqUUGh1e1uSHwCJm2OMUXZDKNJfG4N7p6lPvTCzA0ZxePAw6D6EllhQzNUWWxuJnoPBvFlH1Vul5lB8DTAFDFGDUMKyG4QFOPCHD8DL8YNihDnUtIvwI1Vpub617CtK8IJ2CsYQZygFGr+wg0c5vJBch+vFDJhgEsrSfakznA+1LUSlR5Du4sK/PsnZqwvcSxCbQRrkf01Sh9VpKCkscl98thS403J5xHvkUEN/KUcU6TVxMiTOcFnrYdShvN36Vv9XRlwAj6dsTOUsgmybsaZDxwRPPKkBi6IEY0NYgyfx6XYXn+Q56ZOFhaUCSew9Tofs72hNf+LhvQj3PgE1vIsxaPLhzWdYYTJ3LALjdNGyXYFTA4SeH38Z3vX7++rQGExfQfnvaC7Bp8Q1AnceagrYazptq4W0JjNFTt1mtrrUKrloJGH1sKB8r1RCzdx5ITMf0JbA7+TRx4n+dnSRCY0dBnrd1fO2D4MjWQBIEL+Pz/t6ryYimIe3EtK1QA6cIBLOFGaQ0HdaIX6vwyYPpsDWBuyYZKMWHsIJMdAa3wn6GgaePl/Gn5AQb1oRUfpr1AUndnqejnMDFDxhkhMwkI2cJ5gb7cZBCBXkWIErT6dR8ACypg/Lf7chsw/Uw8A31vkZxy0IIL+Q+YBEQr8l0M9S9vPz6VvWG+lUVzL5rlC07cObZoGVnVy403QYiChHWiwSudNMPdVh06+fub4Q5/y/utIwuQ1yqB+U4sKyouEyEUaC0+lVYbM5iMTGvbozw0HuWAQCMqpbMCMQw9CfuGTVGjuxnJPH6g8gIOFyQB76iyQmmFARdNpczadDuHoMHMnxpe2XR8PMyN9puTXmqsAFSccDEkA1qv8RhoLWau2HyHYFkkjfc3OFrKscBnSaTGgsuEjtM6JKwt+cQxleMlQUVz/0MP0ylrqdOXPFc40WJ+d5Bd9MFBS9Ju8A8C1Tr5D6/XONY41WWTz2HhYOcxyggsprUCcPGTJrKEDLkyavAMzlhmVb0d261EaweFOdFr9oHWqOkgWXQrZYRVg8gGpRhDZW8KybgN9z7eq6grgQpPf0jFSdOeXVXHAdOII3mS/X9Tgjr792i8dU9rbIYxlolV+YPCuqWc5Q50GaJCwE4f/dAeNFv+7Iqd5ThKBgNTgUWC6R86qCxA0oAMeo8+1k803g1ErYvb4Z5CGJ2MycrGJl2mqh5uXweu0NT4ekHiGZrXU8MvC8gPx3eZscXuzfoQPWMuVBu6716UFyfFZnugOJmtSg9l6yXQNqVZDRBeZe1az2VS6lZanQQWeI3dRUtFGO1efh0kf9YIyZAa+N+MLFBezxY9JIHJtAY16lWQqYibgOorEJGUqS2eCOYcU5aQBZkGzDIYCeX8Iva4LOv/3w2F0z4BdkJEw5zIpiYtvZIZWbaMbr5bgvAUAg+INObvNqkzLwvIg5BjXqT+ywnpLDsiaqlFHrNnRBf5os8NUfR1cxH774pyEPgzfphs8sVaZ9fmZ9ho9lSEIwqQVnKKSTPg27hOwsz8XEn6XoUoxfWwZM7z0oaw+sQnripjI7kllOzgKeuRTPqyaeyiN4EifpRD0I53lXEqmCLAPzucIgYVpNd7xkAGKDucPaluUGpkbqqfWZHvkbgMI", | ||
"publicParams": "ACK6MI2KosIo/Ne0RZJByuVUKryZrCnvS1NBCKBqaEVMBK8WjHp29d0uqYTrW1YsU1zNEzA9nVVQoi2+dumkG2XMsW9pgMcG7c0Ms63XPauVr/QTKZZUqqehXtdckDGsYvIWVHoslT8CotrCdF5fkVFJMZLBEfPbWhxVjtBlEkcRDg17pftwEK0Xz+e2S42R8HfnpfnP9WV5ifvyJ7BevyB4HXwo63P8gVllmjDhWDuI57F2dr1T/tZnE7+TxeueD5jDxjaN2+bgE3uGf2xCt+RG+dT/1nkyFpZk02jXj/tpTJWFHuLw9GBo3RHxH8jQnPxEJHxqUUGh1e1uSHwCJm2OMUXZDKNJfG4N7p6lPvTCzA0ZxePAw6D6EllhQzNUWSBC/j8/7eq8mIpiHtxLStUAOnCASzhRmkNB3WiF+r8MmD6bA1gbsmGSjFh7CCTHQGt8J+hoGnj5fxp+QEG9aEUuTJq8AzOWGZVvR3brURrB4U50Wv2gdao6SBZdCtlhFWDyAalGENlbwrJuA33Pt6rqCuBCk9/SMVJ055dVccB0ChRR/UbI42KofhXyURYrxuKfbUSFyq4sV+AbOi+/vQWCgq6IZT4v9Pdz+MWA0+GJcddlgzw8hUOULvWbU8KUBPCOPKV2lbY68ywJOkJu6HWGJRqeCk1d8Dt215D1hh9I+nSI0UNSI0R9fGtnPi/IQO3JANB+g8j5WYMlaiRR/Wj2oVXojkoE7aEL/WBpf0FrVDxnvEpT0/57J1Gs19qHGWzXqWxqc/P+VwyT7/4k7tvCs17cRn3wB/Qrk4Kt/FgayK69dgwv5AwAv6Kv/vShoFirVxPlIKeyUjESLK4GtXwImXSJUL3QCBmYfWt+1O3yUZIaFV404UibUjtx6j69EQ==", | ||
"genericSecretParams": "AD+z/Pi9BEZP+4oZGptLHKWZnFpBi241D1HIFGXjo0cN64psuZguJKjqzL/DUfwweb49VrcZ1tGBC9wTvFPDxg/AY3XI4BYDcAgjzkw4R35zzYKSPGp6zMK0zEPXJSDvKT5523l04Sjy2lBhs74tY2+gJYMae+dXMej9WDLYNg4GcA8yecHPhG2IXvXM5M9O1jLzbcsotPiWlzI2MnkfeweYFL376jbL6Wu+GY4r/Y8XhSfYcLU9gA2bhPshKNmKDbT9l+LttSjlLKnECGihn0KX3Cnro1Qek40WI7qDcc4HPP468mqIdc6bm9SB87MAzRYf9sLD/rkQayf6R+8O4QKUlOxhhncVgE2QQ/KJ5lRZwWPMwsrgP6OnJZCF6bxHBydIYc5RuJa6twxTYegO7eGZuLmNy1Ku3vqBYtmmKMwEfBVHKgTQoxvL5cAy05cnH6jOnCShg2QGGwSsZsxSKgLGyN1FS176CIaqDSZeYJ6ttW8E9J14/yDiROmVqL9pBg==", | ||
"genericPublicParams": "ADZbMQozz5OqOMr7CDAxlhJsLy1mgfZf0sKmxqbCpqshgNntJOvACWmgDT2Ah1CgZRtxDpPKUHcUXHvqupgellEkx07c9O05ha3AsYUjOeRS8Fos8L4Jqibp5zDx7Hd1BFpcpe3bKYYxJaIekPkXCz215RZj4WxqowpxaFb3pqsX+B1JQQ3Rd4FRj14N67dqKvLtIHrJqXwW0T0rBz5CkHbG7Inx+3UTJvb/16uiGJIZTM4BnH/31U9V2zD+PATiQ6I5o0Jn0mD9DStujm+KwU30r3Qk4yB/UwWGG66yoqgR", | ||
"backupSecretParams": "APTh0IoNHMJE2Q7hF2zfSgr5B92mEBNrWhfnkITEpT4MoxbFF1o8nEMWSmWT54NKOyC5wcdth/Fwa0Ha+Pn6gQxQ0Q+/XEmSzDETtxPUUO8yYsy5sTrpZbbeIhJN3Jj0bENH/bo1RA/kUyASqi2afKpGKjkievzW7/bfM2wL6CsPdSAW3G3zLFT1kNnMa4Ys+ppUkjP7zt4SBPnsjsInwQb5EsnEuynVugo1acRUtD14p2verWYkS2tqrBuNpPqpBDtKxjLvtXxpI5WJ0ChYuGPFqsLeBJiZMY9bLiT0MekK0vc4D9RsEwFJYpsXS7BiWGRlSyu0a0swrhozhewUYgYLK0y3/PVEuZ6geuJzzXafvpmOXOYRY197VF3DRBDiCeM9sZXvdxhKodrKUhv3y2Qx3anuILLqDOS+L2VU5ssKQ38l5duJeZ+8ZkhKJUILQFGPEwBq2FHABTevCCZ6DgszALdy9Hsz+n56z8jHDPMNr53W7dj6ron5uarV8aHFAQ==", | ||
"backupPublicParams": "AAKqRyanOBPVl/ujTGopMXOhhzaYqLUCy45p31DztqQdBuG3hss6fzCffFYb7VvhflJuxKvN6Dwc2/4ADcI+gk/6nhPBT1ZBJ4psmCv2keDOseaz8iz43SG27W2OZTB6SI5GP5jFvBLo6Efk6TWsjKrmnkr5s1DxfsT7yXFwFi1GzGL80oYsdtad6YOYJvKoIKwTxtN58DS9HZQn5pyFuBJSRXV5kSbgXBofLH54NGifQQoMc3qQXsEM02dieBBiE85q6CPLZBxSvIgSpHRnetu0f4fGhQzQdUjvRpHt/pNY" | ||
} |
{ | ||
"name": "@signalapp/mock-server", | ||
"version": "7.0.2", | ||
"version": "7.1.0", | ||
"description": "Mock Signal Server for writing tests", | ||
@@ -46,3 +46,3 @@ "main": "src/index.js", | ||
"@indutny/parallel-prettier": "^3.0.0", | ||
"@signalapp/libsignal-client": "^0.45.0", | ||
"@signalapp/libsignal-client": "^0.58.2", | ||
"@tus/file-store": "^1.4.0", | ||
@@ -49,0 +49,0 @@ "@tus/server": "^1.7.0", |
@@ -20,2 +20,4 @@ /// <reference types="node" /> | ||
genericPublicParams: string; | ||
backupSecretParams: string; | ||
backupPublicParams: string; | ||
}>; | ||
@@ -22,0 +24,0 @@ export type Config = Readonly<{ |
@@ -70,2 +70,4 @@ "use strict"; | ||
this.genericServerSecret = new zkgroup_1.GenericServerSecretParams(genericSecret); | ||
const backupSecret = Buffer.from(this.config.zkParams.backupSecretParams, 'base64'); | ||
this.backupServerSecret = new zkgroup_1.GenericServerSecretParams(backupSecret); | ||
this.certificate = (0, crypto_1.generateServerCertificate)(this.trustRoot); | ||
@@ -72,0 +74,0 @@ this.provisionQueue = this.createQueue(); |
export type Certificates = Readonly<{ | ||
certificateAuthority: string; | ||
genericServerPublicParams: string; | ||
backupServerPublicParams: string; | ||
serverPublicParams: string; | ||
@@ -5,0 +6,0 @@ serverTrustRoot: string; |
@@ -25,5 +25,6 @@ "use strict"; | ||
async function load() { | ||
const [certificateAuthority, genericServerPublicParams, serverPublicParams, serverTrustRoot,] = await Promise.all([ | ||
const [certificateAuthority, genericServerPublicParams, backupServerPublicParams, serverPublicParams, serverTrustRoot,] = await Promise.all([ | ||
loadString('ca-cert.pem'), | ||
loadJSONProperty('zk-params.json', 'genericPublicParams'), | ||
loadJSONProperty('zk-params.json', 'backupPublicParams'), | ||
loadJSONProperty('zk-params.json', 'publicParams'), | ||
@@ -35,2 +36,3 @@ loadJSONProperty('trust-root.json', 'publicKey'), | ||
genericServerPublicParams, | ||
backupServerPublicParams, | ||
serverPublicParams, | ||
@@ -37,0 +39,0 @@ serverTrustRoot, |
@@ -1,2 +0,1 @@ | ||
/// <reference types="node" /> | ||
import z from 'zod'; | ||
@@ -437,2 +436,29 @@ import { AciString, DeviceId, PniString, RegistrationId } from '../types'; | ||
export type DeleteCallLink = z.infer<typeof DeleteCallLinkSchema>; | ||
export declare const SetBackupIdSchema: z.ZodObject<{ | ||
backupAuthCredentialRequest: z.ZodEffects<z.ZodString, Buffer, string>; | ||
}, "strip", z.ZodTypeAny, { | ||
backupAuthCredentialRequest: Buffer; | ||
}, { | ||
backupAuthCredentialRequest: string; | ||
}>; | ||
export type SetBackupId = z.infer<typeof SetBackupIdSchema>; | ||
export declare const BackupHeadersSchema: z.ZodObject<{ | ||
'x-signal-zk-auth': z.ZodEffects<z.ZodString, Buffer, string>; | ||
'x-signal-zk-auth-signature': z.ZodEffects<z.ZodString, Buffer, string>; | ||
}, "strip", z.ZodTypeAny, { | ||
'x-signal-zk-auth': Buffer; | ||
'x-signal-zk-auth-signature': Buffer; | ||
}, { | ||
'x-signal-zk-auth': string; | ||
'x-signal-zk-auth-signature': string; | ||
}>; | ||
export type BackupHeaders = z.infer<typeof BackupHeadersSchema>; | ||
export declare const SetBackupKeySchema: z.ZodObject<{ | ||
backupIdPublicKey: z.ZodEffects<z.ZodString, Buffer, string>; | ||
}, "strip", z.ZodTypeAny, { | ||
backupIdPublicKey: Buffer; | ||
}, { | ||
backupIdPublicKey: string; | ||
}>; | ||
export type SetBackupKey = z.infer<typeof SetBackupKeySchema>; | ||
export {}; |
@@ -8,3 +8,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.DeleteCallLinkSchema = exports.UpdateCallLinkSchema = exports.CreateCallLinkSchema = exports.CreateCallLinkAuthSchema = exports.PutUsernameLinkSchema = exports.UsernameConfirmationSchema = exports.UsernameReservationSchema = exports.GroupStateSchema = exports.AtomicLinkingDataSchema = exports.MessageListSchema = exports.MessageSchema = exports.DeviceKeysSchema = exports.DeviceIdSchema = exports.RegistrationIdSchema = exports.ServiceIdSchema = exports.PniSchema = exports.AciSchema = exports.PositiveInt = void 0; | ||
exports.SetBackupKeySchema = exports.BackupHeadersSchema = exports.SetBackupIdSchema = exports.DeleteCallLinkSchema = exports.UpdateCallLinkSchema = exports.CreateCallLinkSchema = exports.CreateCallLinkAuthSchema = exports.PutUsernameLinkSchema = exports.UsernameConfirmationSchema = exports.UsernameReservationSchema = exports.GroupStateSchema = exports.AtomicLinkingDataSchema = exports.MessageListSchema = exports.MessageSchema = exports.DeviceKeysSchema = exports.DeviceIdSchema = exports.RegistrationIdSchema = exports.ServiceIdSchema = exports.PniSchema = exports.AciSchema = exports.PositiveInt = void 0; | ||
const zod_1 = __importDefault(require("zod")); | ||
@@ -106,1 +106,11 @@ const util_1 = require("../util"); | ||
}); | ||
exports.SetBackupIdSchema = zod_1.default.object({ | ||
backupAuthCredentialRequest: zod_1.default.string().transform(util_1.fromBase64), | ||
}); | ||
exports.BackupHeadersSchema = zod_1.default.object({ | ||
'x-signal-zk-auth': zod_1.default.string().transform(util_1.fromBase64), | ||
'x-signal-zk-auth-signature': zod_1.default.string().transform(util_1.fromBase64), | ||
}); | ||
exports.SetBackupKeySchema = zod_1.default.object({ | ||
backupIdPublicKey: zod_1.default.string().transform(util_1.fromBase64), | ||
}); |
@@ -12,3 +12,3 @@ /// <reference types="node" /> | ||
import { ChangeNumberOptions, Device, DeviceKeys } from '../data/device'; | ||
import { CreateCallLink, DeleteCallLink, Message, UpdateCallLink, UsernameConfirmation, UsernameReservation } from '../data/schemas'; | ||
import { BackupHeaders, CreateCallLink, DeleteCallLink, Message, SetBackupId, SetBackupKey, UpdateCallLink, UsernameConfirmation, UsernameReservation } from '../data/schemas'; | ||
import { AciString, AttachmentId, DeviceId, PniString, ProvisionIdString, ProvisioningCode, RegistrationId, ServiceIdKind, ServiceIdString } from '../types'; | ||
@@ -26,3 +26,3 @@ import { ModifyGroupResult, ServerGroup } from './group'; | ||
}>; | ||
export type GroupCredentialsRange = Readonly<{ | ||
export type CredentialsRange = Readonly<{ | ||
from: number; | ||
@@ -38,3 +38,3 @@ to: number; | ||
}>; | ||
export type GroupCredentials = Array<{ | ||
export type Credentials = Array<{ | ||
credential: string; | ||
@@ -126,2 +126,15 @@ redemptionTime: number; | ||
}>; | ||
export type BackupInfo = Readonly<{ | ||
cdn: 3; | ||
backupDir: string; | ||
mediaDir: string; | ||
backupName: string; | ||
usedSpace?: number; | ||
}>; | ||
export type AttachmentUploadForm = Readonly<{ | ||
cdn: 3; | ||
key: string; | ||
headers: Record<string, string>; | ||
signedUploadLocation: string; | ||
}>; | ||
export declare abstract class Server { | ||
@@ -150,5 +163,9 @@ private readonly devices; | ||
private readonly callLinksByRoomId; | ||
private readonly backupAuthReqByAci; | ||
private readonly backupKeyById; | ||
private readonly backupCDNPasswordById; | ||
protected privCertificate: ServerCertificate | undefined; | ||
protected privZKSecret: ServerSecretParams | undefined; | ||
protected privGenericServerSecret: GenericServerSecretParams | undefined; | ||
protected privBackupServerSecret: GenericServerSecretParams | undefined; | ||
protected https: https.Server | undefined; | ||
@@ -172,2 +189,3 @@ address(): AddressInfo; | ||
storeStickerPack(pack: EncryptedStickerPack): Promise<void>; | ||
getAttachmentUploadForm(key: string): Promise<AttachmentUploadForm>; | ||
prepareMultiDeviceMessage(source: Device | undefined, targetServiceId: ServiceIdString, messages: ReadonlyArray<Message>): Promise<PrepareMultiDeviceMessageResult>; | ||
@@ -213,6 +231,14 @@ handlePreparedMultiDeviceMessage(source: Device | undefined, targetServiceId: ServiceIdString, prepared: PreparedMultiDeviceMessage): Promise<void>; | ||
getSenderCertificate(device: Device): Promise<SenderCertificate>; | ||
getGroupCredentials({ aci, pni }: Device, { from, to }: GroupCredentialsRange, flags?: GroupCredentialsFlags): Promise<GroupCredentials>; | ||
getGroupCredentials({ aci, pni }: Device, range: CredentialsRange, flags?: GroupCredentialsFlags): Promise<Credentials>; | ||
verifyGroupCredentials(publicParams: Buffer, credential: Buffer): Promise<AuthCredentialPresentation>; | ||
getCallLinkAuthCredentials({ aci }: Device, { from, to }: GroupCredentialsRange): Promise<GroupCredentials>; | ||
getCallLinkAuthCredentials({ aci }: Device, range: CredentialsRange): Promise<Credentials>; | ||
issueExpiringProfileKeyCredential({ aci, profileKeyCommitment }: Device, request: ProfileKeyCredentialRequest): Promise<Buffer | undefined>; | ||
setBackupId({ aci }: Device, { backupAuthCredentialRequest }: SetBackupId): Promise<void>; | ||
setBackupKey(headers: BackupHeaders, { backupIdPublicKey }: SetBackupKey): Promise<void>; | ||
refreshBackup(headers: BackupHeaders): Promise<void>; | ||
getBackupInfo(headers: BackupHeaders): Promise<BackupInfo>; | ||
getBackupUploadForm(headers: BackupHeaders): Promise<AttachmentUploadForm>; | ||
getBackupCDNAuth(headers: BackupHeaders): Promise<Record<string, string>>; | ||
authorizeBackupCDN(backupId: string, password: string): Promise<boolean>; | ||
getBackupCredentials({ aci }: Device, range: CredentialsRange): Promise<Credentials | undefined>; | ||
abstract isUnregistered(serviceId: ServiceIdString): boolean; | ||
@@ -225,5 +251,9 @@ abstract isSendRateLimited(options: IsSendRateLimitedOptions): boolean; | ||
protected get genericServerSecret(): GenericServerSecretParams; | ||
protected set backupServerSecret(value: GenericServerSecretParams); | ||
protected get backupServerSecret(): GenericServerSecretParams; | ||
protected set zkSecret(value: ServerSecretParams); | ||
protected get zkSecret(): ServerSecretParams; | ||
private sendQueue; | ||
private issueCredentials; | ||
private authenticateBackup; | ||
} |
@@ -55,5 +55,9 @@ "use strict"; | ||
callLinksByRoomId = new Map(); | ||
backupAuthReqByAci = new Map(); | ||
backupKeyById = new Map(); | ||
backupCDNPasswordById = new Map(); | ||
privCertificate; | ||
privZKSecret; | ||
privGenericServerSecret; | ||
privBackupServerSecret; | ||
https; | ||
@@ -259,2 +263,17 @@ address() { | ||
} | ||
async getAttachmentUploadForm(key) { | ||
const { port, family } = this.address(); | ||
// These are the only two in the TLS certificate | ||
const host = family === 'IPv6' ? '[::1]' : '127.0.0.1'; | ||
const signedUploadLocation = `https://${host}:${port}/cdn3/${key}`; | ||
return { | ||
cdn: 3, | ||
key, | ||
headers: { | ||
// TODO(indutny): verify on request | ||
expectedHeaders: crypto_1.default.randomBytes(16).toString('hex'), | ||
}, | ||
signedUploadLocation, | ||
}; | ||
} | ||
// | ||
@@ -735,11 +754,4 @@ // Messages | ||
} | ||
async getGroupCredentials({ aci, pni }, { from, to }, flags = { zkc: false }) { | ||
const today = (0, util_1.getTodayInSeconds)(); | ||
if (from > to || | ||
from < today || | ||
to > today + constants_1.DAY_IN_SECONDS * constants_1.MAX_GROUP_CREDENTIALS_DAYS) { | ||
throw new Error('Invalid redemption range'); | ||
} | ||
async getGroupCredentials({ aci, pni }, range, flags = { zkc: false }) { | ||
const auth = new zkgroup_1.ServerZkAuthOperations(this.zkSecret); | ||
const result = []; | ||
const { zkc } = flags; | ||
@@ -749,11 +761,5 @@ const issueCredential = zkc | ||
: auth.issueAuthCredentialWithPniAsServiceId.bind(auth); | ||
for (let redemptionTime = from; redemptionTime <= to; redemptionTime += constants_1.DAY_IN_SECONDS) { | ||
result.push({ | ||
credential: issueCredential(libsignal_client_1.Aci.parseFromServiceIdString(aci), libsignal_client_1.Pni.parseFromServiceIdString(pni), redemptionTime) | ||
.serialize() | ||
.toString('base64'), | ||
redemptionTime, | ||
}); | ||
} | ||
return result; | ||
return this.issueCredentials(range, (redemptionTime) => { | ||
return issueCredential(libsignal_client_1.Aci.parseFromServiceIdString(aci), libsignal_client_1.Pni.parseFromServiceIdString(pni), redemptionTime); | ||
}); | ||
} | ||
@@ -768,19 +774,6 @@ async verifyGroupCredentials(publicParams, credential) { | ||
} | ||
async getCallLinkAuthCredentials({ aci }, { from, to }) { | ||
const today = (0, util_1.getTodayInSeconds)(); | ||
if (from > to || | ||
from < today || | ||
to > today + constants_1.DAY_IN_SECONDS * constants_1.MAX_GROUP_CREDENTIALS_DAYS) { | ||
throw new Error('Invalid redemption range'); | ||
} | ||
const result = []; | ||
for (let redemptionTime = from; redemptionTime <= to; redemptionTime += constants_1.DAY_IN_SECONDS) { | ||
result.push({ | ||
credential: zkgroup_1.CallLinkAuthCredentialResponse.issueCredential(libsignal_client_1.Aci.parseFromServiceIdString(aci), redemptionTime, this.genericServerSecret) | ||
.serialize() | ||
.toString('base64'), | ||
redemptionTime, | ||
}); | ||
} | ||
return result; | ||
async getCallLinkAuthCredentials({ aci }, range) { | ||
return this.issueCredentials(range, (redemptionTime) => { | ||
return zkgroup_1.CallLinkAuthCredentialResponse.issueCredential(libsignal_client_1.Aci.parseFromServiceIdString(aci), redemptionTime, this.genericServerSecret); | ||
}); | ||
} | ||
@@ -797,2 +790,64 @@ async issueExpiringProfileKeyCredential({ aci, profileKeyCommitment }, request) { | ||
} | ||
async setBackupId({ aci }, { backupAuthCredentialRequest }) { | ||
const req = new zkgroup_1.BackupAuthCredentialRequest(backupAuthCredentialRequest); | ||
this.backupAuthReqByAci.set(aci, req); | ||
} | ||
async setBackupKey(headers, { backupIdPublicKey }) { | ||
const publicKey = libsignal_client_1.PublicKey.deserialize(backupIdPublicKey); | ||
const backupId = this.authenticateBackup(headers, publicKey); | ||
this.backupKeyById.set(backupId, publicKey); | ||
if (!this.backupCDNPasswordById.get(backupId)) { | ||
const password = crypto_1.default.randomBytes(16).toString('hex'); | ||
this.backupCDNPasswordById.set(backupId, password); | ||
} | ||
} | ||
async refreshBackup(headers) { | ||
this.authenticateBackup(headers); | ||
// No-op for tests | ||
} | ||
async getBackupInfo(headers) { | ||
const backupId = this.authenticateBackup(headers); | ||
return { | ||
cdn: 3, | ||
backupDir: backupId, | ||
mediaDir: `media_${backupId}`, | ||
backupName: 'backup', | ||
}; | ||
} | ||
async getBackupUploadForm(headers) { | ||
const backupId = this.authenticateBackup(headers); | ||
const form = await this.getAttachmentUploadForm(`backups/${backupId}/backup`); | ||
return form; | ||
} | ||
async getBackupCDNAuth(headers) { | ||
const backupId = this.authenticateBackup(headers); | ||
const password = this.backupCDNPasswordById.get(backupId); | ||
(0, assert_1.default)(password !== undefined); | ||
const basic = Buffer.from(`${backupId}:${password}`); | ||
const authorization = `Basic ${basic.toString('base64')}`; | ||
return { | ||
authorization, | ||
}; | ||
} | ||
async authorizeBackupCDN(backupId, password) { | ||
const expected = this.backupCDNPasswordById.get(backupId); | ||
if (expected === undefined) { | ||
return false; | ||
} | ||
if (!crypto_1.default.timingSafeEqual(Buffer.from(expected), Buffer.from(password))) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
async getBackupCredentials({ aci }, range) { | ||
const req = this.backupAuthReqByAci.get(aci); | ||
if (req === undefined) { | ||
return undefined; | ||
} | ||
return this.issueCredentials(range, (redemptionTime) => { | ||
return req.issueCredential(redemptionTime, | ||
// TODO(indutny): offer different levels | ||
zkgroup_1.BackupLevel.Messages, this.backupServerSecret); | ||
}); | ||
} | ||
// | ||
@@ -825,2 +880,14 @@ // Private | ||
} | ||
set backupServerSecret(value) { | ||
if (this.privBackupServerSecret) { | ||
throw new Error('zkgroup backup secret already set'); | ||
} | ||
this.privBackupServerSecret = value; | ||
} | ||
get backupServerSecret() { | ||
if (!this.privBackupServerSecret) { | ||
throw new Error('zkgroup backup secret not set'); | ||
} | ||
return this.privBackupServerSecret; | ||
} | ||
set zkSecret(value) { | ||
@@ -862,3 +929,34 @@ if (this.privZKSecret) { | ||
} | ||
issueCredentials({ from, to }, issueOne) { | ||
const today = (0, util_1.getTodayInSeconds)(); | ||
if (from > to || | ||
from < today || | ||
to > today + constants_1.DAY_IN_SECONDS * constants_1.MAX_GROUP_CREDENTIALS_DAYS) { | ||
throw new Error('Invalid redemption range'); | ||
} | ||
const result = []; | ||
for (let redemptionTime = from; redemptionTime <= to; redemptionTime += constants_1.DAY_IN_SECONDS) { | ||
result.push({ | ||
credential: issueOne(redemptionTime).serialize().toString('base64'), | ||
redemptionTime, | ||
}); | ||
} | ||
return result; | ||
} | ||
authenticateBackup(headers, newPublicKey) { | ||
const presentation = new zkgroup_1.BackupAuthCredentialPresentation(headers['x-signal-zk-auth']); | ||
presentation.verify(this.backupServerSecret); | ||
// Backup id is used in urls, so encode it properly | ||
const backupId = presentation.getBackupId().toString('base64url'); | ||
const validatingKey = this.backupKeyById.get(backupId) || newPublicKey; | ||
if (!validatingKey) { | ||
throw new Error('No backup public key to validate against'); | ||
} | ||
const isValid = validatingKey.verify(headers['x-signal-zk-auth'], headers['x-signal-zk-auth-signature']); | ||
if (!isValid) { | ||
throw new Error('Invalid signature'); | ||
} | ||
return backupId; | ||
} | ||
} | ||
exports.Server = Server; |
@@ -114,9 +114,26 @@ "use strict"; | ||
(0, assert_1.default)(req.url); | ||
return req.url.split('/').at(-1); | ||
return req.url.replace(/^(\/cdn3)?\/+/, ''); | ||
}, | ||
}); | ||
const getCdn3Attachment = (0, microrouter_1.get)('/cdn3/attachments/:key', async (req, res) => { | ||
const getCdn3Attachment = (0, microrouter_1.get)('/cdn3/:folder/*', async (req, res) => { | ||
(0, assert_1.default)(cdn3Path, 'cdn3Path must be set'); | ||
if (req.params.folder === 'backups') { | ||
const { username, password, error } = parsePassword(req); | ||
if (error) { | ||
debug('%s %s backup cdn auth failed, error %j', req.method, req.url, error); | ||
(0, micro_1.send)(res, 401, { error }); | ||
return; | ||
} | ||
if (!username || !password) { | ||
(0, micro_1.send)(res, 401, { error: 'Missing username and/or password' }); | ||
return; | ||
} | ||
const authorized = await server.authorizeBackupCDN(username, password); | ||
if (!authorized) { | ||
(0, micro_1.send)(res, 403, { error: 'Invalid password' }); | ||
return; | ||
} | ||
} | ||
try { | ||
const data = fs.readFileSync((0, path_1.join)(cdn3Path, req.params.key)); | ||
const data = fs.readFileSync((0, path_1.join)(cdn3Path, req.params.folder, req.params._)); | ||
return (0, micro_1.send)(res, 200, data); | ||
@@ -133,2 +150,3 @@ } | ||
const getAttachment = (0, microrouter_1.get)('/attachments/:key', async (req, res) => { | ||
// TODO(indutny): range requests | ||
const { key } = req.params; | ||
@@ -695,5 +713,12 @@ const result = await server.fetchAttachment(key); | ||
debug('got request %s %s', req.method, req.url); | ||
return routes(req, res); | ||
try { | ||
return routes(req, res); | ||
} | ||
catch (error) { | ||
(0, assert_1.default)(error instanceof Error); | ||
debug('request failure %s %s', req.method, req.url, error.stack); | ||
return (0, micro_1.send)(res, 500, error.message); | ||
} | ||
}; | ||
}; | ||
exports.createHandler = createHandler; |
@@ -76,7 +76,7 @@ "use strict"; | ||
const requireAuth = (handler) => { | ||
return async (params, body, headers) => { | ||
return async (params, body, headers, query) => { | ||
if (!this.device) { | ||
return [401, { error: 'Not authorized' }]; | ||
} | ||
return handler(params, body, headers); | ||
return handler(params, body, headers, query); | ||
}; | ||
@@ -89,14 +89,5 @@ }; | ||
config: [ | ||
{ name: 'desktop.gv2', enabled: true }, | ||
{ name: 'desktop.gv2Admin', enabled: true }, | ||
{ name: 'desktop.internalUser', enabled: true }, | ||
{ name: 'desktop.sendSenderKey2', enabled: true }, | ||
{ name: 'desktop.sendSenderKey3', enabled: true }, | ||
{ name: 'desktop.senderKey.retry', enabled: true }, | ||
{ name: 'desktop.senderKey.send', enabled: true }, | ||
{ name: 'desktop.storage', enabled: true }, | ||
{ name: 'desktop.storageWrite3', enabled: true }, | ||
{ name: 'desktop.messageRequests', enabled: true }, | ||
{ name: 'desktop.pnp', enabled: true }, | ||
{ name: 'desktop.usernames', enabled: true }, | ||
{ name: 'desktop.backup.credentialFetch', enabled: true }, | ||
{ | ||
@@ -323,2 +314,83 @@ name: 'global.groupsv2.maxGroupSize', | ||
// | ||
// Backups | ||
// | ||
this.router.put('/v1/archives/backupid', requireAuth(async (_params, body) => { | ||
const device = this.device; | ||
(0, assert_1.default)(device); | ||
if (!body) { | ||
return [400, { error: 'Missing body' }]; | ||
} | ||
const backupId = schemas_1.SetBackupIdSchema.parse(JSON.parse(body.toString())); | ||
await server.setBackupId(device, backupId); | ||
return [200, { ok: true }]; | ||
})); | ||
this.router.get('/v1/archives/auth', requireAuth(async (_params, _body, _headers, query = {}) => { | ||
const device = this.device; | ||
(0, assert_1.default)(device); | ||
const { redemptionStartSeconds: from, redemptionEndSeconds: to } = query; | ||
const credentials = await this.server.getBackupCredentials(device, { | ||
from: parseInt(from, 10), | ||
to: parseInt(to, 10), | ||
}); | ||
if (credentials === undefined) { | ||
return [404, { error: 'backup id not set' }]; | ||
} | ||
return [ | ||
200, | ||
{ | ||
credentials, | ||
}, | ||
]; | ||
})); | ||
this.router.put('/v1/archives/keys', async (_params, body, headers) => { | ||
if (this.device) { | ||
return [400, { error: 'Extraneous authentication' }]; | ||
} | ||
if (!body) { | ||
return [400, { error: 'Missing body' }]; | ||
} | ||
const backupKey = schemas_1.SetBackupKeySchema.parse(JSON.parse(body.toString())); | ||
await server.setBackupKey(schemas_1.BackupHeadersSchema.parse(headers), backupKey); | ||
return [200, { ok: true }]; | ||
}); | ||
this.router.post('/v1/archives', async (_params, _body, headers) => { | ||
if (this.device) { | ||
return [400, { error: 'Extraneous authentication' }]; | ||
} | ||
await server.refreshBackup(schemas_1.BackupHeadersSchema.parse(headers)); | ||
return [200, { ok: true }]; | ||
}); | ||
this.router.get('/v1/archives', async (_params, _body, headers) => { | ||
if (this.device) { | ||
return [400, { error: 'Extraneous authentication' }]; | ||
} | ||
return [ | ||
200, | ||
await server.getBackupInfo(schemas_1.BackupHeadersSchema.parse(headers)), | ||
]; | ||
}); | ||
this.router.get('/v1/archives/auth/read', async (_params, _body, headers, params = {}) => { | ||
if (this.device) { | ||
return [400, { error: 'Extraneous authentication' }]; | ||
} | ||
if (params.cdn !== '3') { | ||
return [400, { error: 'Invalid cdn query param' }]; | ||
} | ||
return [ | ||
200, | ||
{ | ||
headers: await server.getBackupCDNAuth(schemas_1.BackupHeadersSchema.parse(headers)), | ||
}, | ||
]; | ||
}); | ||
this.router.get('/v1/archives/upload/form', async (_params, _body, headers) => { | ||
if (this.device) { | ||
return [400, { error: 'Extraneous authentication' }]; | ||
} | ||
return [ | ||
200, | ||
await this.server.getBackupUploadForm(schemas_1.BackupHeadersSchema.parse(headers)), | ||
]; | ||
}); | ||
// | ||
// Keepalive | ||
@@ -334,6 +406,3 @@ // | ||
const key = (0, uuid_1.v4)(); | ||
const headers = { expectedHeaders: (0, uuid_1.v4)() }; | ||
const address = this.server.address(); | ||
const signedUploadLocation = `https://127.0.0.1:${address.port}/cdn3/${key}`; | ||
return [200, { cdn: 3, key, headers, signedUploadLocation }]; | ||
return [200, await this.server.getAttachmentUploadForm(key)]; | ||
}); | ||
@@ -340,0 +409,0 @@ } |
@@ -13,4 +13,5 @@ /// <reference types="node" /> | ||
put(pattern: string, handler: Handler): void; | ||
post(pattern: string, handler: Handler): void; | ||
run(request: WSRequest): Promise<WSResponse>; | ||
setIsAuthenticated(value: boolean): void; | ||
} |
@@ -33,2 +33,5 @@ "use strict"; | ||
} | ||
post(pattern, handler) { | ||
this.register('POST', pattern, handler); | ||
} | ||
async run(request) { | ||
@@ -35,0 +38,0 @@ const headers = {}; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
3872862
71341
+ Added@signalapp/libsignal-client@0.58.3(transitive)
- Removed@signalapp/libsignal-client@0.45.1(transitive)
- Removedtype-fest@3.13.1(transitive)