This library was developed as part of my PhD thesis, presenting the design and implementation of a client library that enables secure storage of messages on the server side using the Labyrinth protocol developed by Meta.
The purpose of this library is to facilitate discussions, analysis, and improvements of the protocol while also detailing certain issues that may be helpful for further development.
Library can be installed via npm:
npm i @sebastianp265/safe-server-side-storage-client
Example usages are provided below. Additionally, real-life usage can be found in the repository e2ee-chat-with-labyrinth, which demonstrates integration in a messaging app using React.
Library requires to implement communication with the server through LabyrinthServerClient API:
const labyrinthServerClient: LabyrinthServerClient = {
/*
Implementation of API layer communication
*/
// For example:
openFirstEpoch: async (requestBody) =>
(
await httpClient.post<OpenFirstEpochResponse>(
`${labyrinthServicePrefix}/epochs/open-first`,
requestBody,
)
).data,
};
All actions are available via Labyrinth instance, which must be created using static methods based on the scenario.
const userId = "example-user-id";
const { labyrinthInstance, recoveryCode } = await Labyrinth.initialize(
userId,
labyrinthServerClient,
);
const userId = "example-user-id";
const labyrinthInstance = await Labyrinth.fromRecoveryCode(
userId,
recoveryCode,
labyrinthServerClient,
);
// For example:
const labyrinthSerialized = JSON.parse(localStorage.getItem("labyrinth"))
const labyrinthInstance = await Labyrinth.deserialize(labyrinthSerialized, labyrinthServerClient)
const textEncoder = new TextEncoder();
const exampleMessage = JSON.stringify({
content: "example-message-content",
authorId: "example-author-id",
});
const encryptedMessage = labyrinthInstance.encrypt(
"example-thread-id",
labyrinthInstance.getNewestEpochSequenceId(),
textEncoder.encode(exampleMessage),
);
const textDecoder = new TextDecoder();
const decryptedMessage = textDecoder.decode(
labyrinthInstance.decrypt(
"example-thread-id",
labyrinthInstance.getNewestEpochSequenceId(),
encryptedMessage,
),
);
assert(decryptedMessage == exampleMessage);
// For example:
localStorage.setItem("labyrinth", JSON.stringify(
labyrinthInstance.serialize()
));
Contributions are welcome! Feel free to open issues and submit pull requests.
The code is not fully covered with tests inside this repository. However, the library is fully functional and has been tested from a usage perspective with Cypress tests in the e2ee-chat-with-labyrinth repository.
To run existing tests:
npm run test
And check code-coverage:
npm run coverage
This library is not yet production-ready and does not guarantee to be secure. It is provided "as is" without any warranties or guarantees of any kind. I take no responsibility for any use, misuse, or consequences arising from the use of this code. Use it at your own risk.