New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@socialgouv/e2esdk-client

Package Overview
Dependencies
Maintainers
2
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@socialgouv/e2esdk-client - npm Package Compare versions

Comparing version

to
1.0.0-beta.21

10

dist/index.d.ts

@@ -11,3 +11,3 @@ import { PermissionFlags } from '@socialgouv/e2esdk-api';

};
type Config = Required<Omit<ClientConfig<Uint8Array>, 'handleSessionRefresh'>> & {
type Config = Required<ClientConfig<Uint8Array>> & {
clientId: string;

@@ -92,5 +92,10 @@ };

enrollNewDevice(label?: string): Promise<string>;
registerEnrolledDevice(qr: string): void;
/**
* Register this device and login
* @param uri device registration URI
*/
registerEnrolledDevice(uri: string): Promise<PublicUserIdentity | null>;
get currentDeviceId(): string | null;
getEnrolledDevices(): Promise<{
label: string | undefined;
id: string;

@@ -103,3 +108,2 @@ createdAt: string;

enrolledFrom?: string | undefined;
label?: string | undefined;
}[]>;

@@ -106,0 +110,0 @@ createKey(label: string, algorithm: 'secretBox' | 'sealedBox', expiresAt?: Date): Promise<KeychainItemMetadata>;

import initOpaqueClient, { Registration, Login } from '@47ng/opaque-client';
import { wasmBase64 } from '@47ng/opaque-client/inline-wasm';
import { thirtyTwoBytesBase64Schema, sixtyFourBytesBase64Schema, fingerprintSchema, timestampSchema, identitySchema as identitySchema$1, signatureSchema, deviceIdSchema, base64Bytes, signupResponse, signupCompleteResponse, loginResponse, loginFinalResponse, deviceSchema, deviceEnrollmentResponse, deviceEnrolledResponse, listDevicesResponseBody, getSharedKeysResponseBody, getSingleIdentityResponseBody, getMultipleIdentitiesResponseBody, getParticipantsResponseBody, permissionFlags, getKeychainResponseBody, websocketNotificationTypesSchema, WebSocketNotificationTypes, responseHeaders, isFarFromCurrentTime } from '@socialgouv/e2esdk-api';
import { thirtyTwoBytesBase64Schema, sixtyFourBytesBase64Schema, fingerprintSchema, timestampSchema, identitySchema as identitySchema$1, signatureSchema, deviceIdSchema, base64Bytes, signupResponse, signupCompleteResponse, encodeDeviceRegistrationURI, loginResponse, loginFinalResponse, deviceSchema, deviceEnrollmentResponse, deviceEnrolledResponse, decodeDeviceRegistrationURI, listDevicesResponseBody, getSharedKeysResponseBody, getSingleIdentityResponseBody, getMultipleIdentitiesResponseBody, getParticipantsResponseBody, permissionFlags, getKeychainResponseBody, websocketNotificationTypesSchema, WebSocketNotificationTypes, responseHeaders, isFarFromCurrentTime } from '@socialgouv/e2esdk-api';
import { base64UrlDecode, cipherParser, sodium, deriveClientIdentity, base64UrlEncode, getOpaqueExportCipher, encrypt, fingerprint, decrypt, getDeviceLabelCipher, generateSealedBoxCipher, generateSecretBoxCipher, serializeCipher, encodedCiphertextFormatV1, randomPad, CIPHER_MAX_PADDED_LENGTH, multipartSignature, numberToUint32LE, verifyClientIdentity, decryptFormData, verifyMultipartSignature, memzeroCipher, signAuth, verifyAuth } from '@socialgouv/e2esdk-crypto';

@@ -11,2 +11,3 @@ import { LocalStateSync } from 'local-state-sync';

// src/index.ts
var SESSION_REFRESH_RETRY_COUNT = 3;
var NAME_PREFIX_LENGTH_BYTES = 32;

@@ -69,3 +70,3 @@ var NAME_PREFIX_SEPARATOR = ":";

]);
var deviceSecretSchema = base64Bytes(32);
base64Bytes(32);
var Client = class {

@@ -79,3 +80,3 @@ sodium;

#socketExponentialBackoffTimeout;
#handleSessionRefresh;
#sessionRefreshRetryCount;
constructor(config) {

@@ -91,5 +92,6 @@ const tick = performance.now();

handleNotifications: config.handleNotifications ?? true,
handleSessionRefresh: config.handleSessionRefresh ?? true,
clientId: typeof crypto === "object" ? crypto.randomUUID() : "not-available-in-ssr"
});
this.#handleSessionRefresh = config.handleSessionRefresh ?? true;
this.#sessionRefreshRetryCount = this.config.handleSessionRefresh ? SESSION_REFRESH_RETRY_COUNT : 0;
this.#state = {

@@ -179,3 +181,10 @@ state: "idle"

registrationRecord,
wrappedMainKey: encrypt(this.sodium, mainKey, mainKeyWrappingCipher),
wrappedMainKey: encrypt(
this.sodium,
mainKey,
mainKeyWrappingCipher,
// Bind the ciphertext to the userId as authenticated additional data
sodium.from_string(userId),
"application/e2esdk.ciphertext.v1"
),
signaturePublicKey: base64UrlEncode(identity.signature.publicKey),

@@ -200,3 +209,3 @@ sharingPublicKey: base64UrlEncode(identity.sharing.publicKey),

this.registerEnrolledDevice(
this.#encodeDeviceRegistrationQR(userId, deviceId, deviceSecret)
encodeDeviceRegistrationURI(userId, deviceId, deviceSecret)
);

@@ -254,3 +263,10 @@ } catch (error) {

const mainKeyWrappingCipher = getOpaqueExportCipher(this.sodium, exportKey);
const mainKey = z.instanceof(Uint8Array).parse(decrypt(this.sodium, wrappedMainKey, mainKeyWrappingCipher));
const mainKey = z.instanceof(Uint8Array).parse(
decrypt(
this.sodium,
wrappedMainKey,
mainKeyWrappingCipher,
this.sodium.from_string(userId)
)
);
const identity = deriveClientIdentity(this.sodium, userId, mainKey);

@@ -290,3 +306,8 @@ this.sodium.memzero(mainKey);

const mainKey = z.instanceof(Uint8Array).parse(
decrypt(this.sodium, device.wrappedMainKey, mainKeyUnwrappingCipher)
decrypt(
this.sodium,
device.wrappedMainKey,
mainKeyUnwrappingCipher,
this.sodium.from_string(this.#state.identity.userId)
)
);

@@ -332,3 +353,3 @@ this.sodium.memzero(mainKeyUnwrappingCipher.key);

mainKeyRewrappingCipher,
null,
this.sodium.from_string(this.#state.identity.userId),
"application/e2esdk.ciphertext.v1"

@@ -364,3 +385,3 @@ );

);
return this.#encodeDeviceRegistrationQR(
return encodeDeviceRegistrationURI(
this.#state.identity.userId,

@@ -371,6 +392,17 @@ deviceId,

}
registerEnrolledDevice(qr) {
const { userId, deviceId, deviceSecret } = this.#decodeDeviceRegistrationQR(qr);
/**
* Register this device and login
* @param uri device registration URI
*/
async registerEnrolledDevice(uri) {
const { userId, deviceId, deviceSecret } = decodeDeviceRegistrationURI(uri);
localStorage.setItem(`e2esdk:${userId}:device:id`, deviceId);
localStorage.setItem(`e2esdk:${userId}:device:secret`, deviceSecret);
try {
return await this.login(userId);
} catch (error) {
localStorage.removeItem(`e2esdk:${userId}:device:id`);
localStorage.removeItem(`e2esdk:${userId}:device:secret`);
throw error;
}
}

@@ -384,30 +416,22 @@ get currentDeviceId() {

async getEnrolledDevices() {
return listDevicesResponseBody.parse(
await this.sodium.ready;
if (this.#state.state !== "loaded") {
throw new Error("Account locked: cannot list enrolled devices");
}
const devices = listDevicesResponseBody.parse(
await this.#apiCall("GET", "/v1/auth/devices")
);
}
#encodeDeviceRegistrationQR(userId, deviceId, deviceSecret) {
const qr = new URL("e2esdk://register-device");
qr.searchParams.set("userId", userId);
qr.searchParams.set("deviceId", deviceId);
qr.searchParams.set("deviceSecret", deviceSecret);
return qr.toString();
}
#decodeDeviceRegistrationQR(qr) {
const url = new URL(qr);
if (url.protocol !== "e2esdk:" || url.pathname !== "//register-device") {
throw new Error("Invalid device registration data");
const deviceLabelCipher = getDeviceLabelCipher(
this.sodium,
this.#state.identity.userId,
this.#state.identity.keychainBaseKey
);
try {
return devices.map((device) => ({
...device,
label: device.label ? z.string().parse(decrypt(this.sodium, device.label, deviceLabelCipher)) : void 0
}));
} finally {
this.sodium.memzero(deviceLabelCipher.key);
}
const userId = identitySchema.shape.userId.parse(
url.searchParams.get("userId")
);
const deviceId = deviceIdSchema.parse(url.searchParams.get("deviceId"));
const deviceSecret = deviceSecretSchema.parse(
url.searchParams.get("deviceSecret")
);
return {
userId,
deviceId,
deviceSecret
};
}

@@ -1170,18 +1194,16 @@ // Key Ops --

if (!res.ok) {
if (this.#handleSessionRefresh && res.status === 401) {
try {
console.dir({
signatureItems,
res: await res.json()
});
throw new Error("Aborting infinite login recursion");
this.#handleSessionRefresh = false;
return this.#apiCall(method, path, body);
} finally {
this.#handleSessionRefresh = true;
if (res.status === 401) {
if (this.#sessionRefreshRetryCount === 0) {
const { error: statusText, statusCode, message } = await res.json();
throw new APIError(statusCode, statusText, message);
}
this.#sessionRefreshRetryCount--;
await this.login(this.#state.identity.userId);
return this.#apiCall(method, path, body);
} else {
const { error: statusText, statusCode, message } = await res.json();
throw new APIError(statusCode, statusText, message);
}
const { error: statusText, statusCode, message } = await res.json();
throw new APIError(statusCode, statusText, message);
}
this.#sessionRefreshRetryCount = this.config.handleSessionRefresh ? SESSION_REFRESH_RETRY_COUNT : 0;
return this.#verifyServerResponse(method, res);

@@ -1188,0 +1210,0 @@ }

{
"name": "@socialgouv/e2esdk-client",
"version": "1.0.0-beta.20",
"version": "1.0.0-beta.21",
"license": "Apache-2.0",

@@ -5,0 +5,0 @@ "description": "End-to-end encryption client",

@@ -1,1 +0,1 @@

{"$schema":"https://raw.githubusercontent.com/47ng/sceau/main/src/schemas/v1.schema.json","signature":"291f27e100f3d722fecbc960191ea204c4e60a020731b2f5201919919bbf1fbf92654e3261f4c7530c2ad08c3729a5b34be84d1aa902cca9ea9ef36f1f1b3507","publicKey":"82182691aa16fb18c4ee5f502f9067fe486768391d6ad5baa95e7a68913c9ad9","timestamp":"2023-03-22T13:58:56.225Z","sourceURL":"https://github.com/SocialGouv/e2esdk/tree/574e6ef8c41e71b8db078a59565e8e631823e9b6","buildURL":"https://github.com/SocialGouv/e2esdk/actions/runs/4490605706","manifest":[{"path":"README.md","hash":"4d045827bb62a85317c226a17beb8fcced4f7464c9cd98b1a9f5454f189d6a5e41da42f1b52183dfe66f166371e9caafb80f170af967d8c7b8999fecd6751c0b","sizeBytes":184,"signature":"73db42e6419b8c7b628e73c87229c182557c258a4ec4ed8a270cb01658fbf7b8d1289288d543bf6a8ec85c9f3836ef8d70f7cba18b38604b128b3973d5bcd009"},{"path":"dist/index.cjs","hash":"4341f05178c2e9cd723c826e4f55064bac85760e3f18998b0ca20a71be4f7bb0e27d70d0fb739ebefbbb9c8972532bacad72bae0493ee677ea8259d1a27332bf","sizeBytes":47805,"signature":"b309b243c786906eb27625fb90b4bd72f854dde0421ba65680ad4bf0c9e4d0b91d08b48815a8373e03ba597b2794bcb4e3fc5ef296576fc6664da43a70914406"},{"path":"dist/index.d.ts","hash":"ef070c076de9108201e24ee54b707ded3d4c4dc59996931af65bf7aa8a30b05e54343b80cbceeaf4233c55a0c95f68c7a5a0b1e3edf4c9eedc9a1a0877496487","sizeBytes":6077,"signature":"5cb33fc35e5e02302b093c16d3c360c74a28313bf5dabd5c723b83c651e72d5eaaf9f6274db5d2fdde69141973c16ed17d01e66f2b47acca14c91e573c3b7500"},{"path":"dist/index.js","hash":"c1cace74ad18c0c4d01f7a6a6690ca2fc06f6c2606f78109e06a99b67a356d20cfdffe39e6673dccd11891dfe2d3e39b5ef50e3fad3226091132a42652ac061c","sizeBytes":46520,"signature":"46b7fd11fcfe2a58b7831c74e900dc53c7bf2a9f0ecb8803630e6d309d304f4f641e678c126c841d3dc93f06be0e9b28b71e125bf7deaa667dbac1f07fc28005"},{"path":"package.json","hash":"12887414445b6856eb965c5ca9a44ff33cdd056af318470d8922d844c8cfd03a205c2279621b69a21a1a613e56738a7b3beb890887e0b2ec6ac8dbfa4ef5a623","sizeBytes":1352,"signature":"8535364ca8d04bf7d4cca17a3fb758148f7a623dc3b1e6d06f925f970fe0fb3ac2a43740fa867d74187400924dda1237ccd7df75f67784bb768a0ed0d86ece04"}]}
{"$schema":"https://raw.githubusercontent.com/47ng/sceau/main/src/schemas/v1.schema.json","signature":"c91f990a274c789fc79ab890beb40adee4d79c31f5b895b7a804a2d3c3bc2085a263415d00ee0b28dd59e2015317a8f8e74b1e845eed2f7afeef8a1c3090360e","publicKey":"82182691aa16fb18c4ee5f502f9067fe486768391d6ad5baa95e7a68913c9ad9","timestamp":"2023-03-28T12:21:16.537Z","sourceURL":"https://github.com/SocialGouv/e2esdk/tree/beac0770dd9bc01df9bbe4256bb175adcacf4f7d","buildURL":"https://github.com/SocialGouv/e2esdk/actions/runs/4542914943","manifest":[{"path":"README.md","hash":"4d045827bb62a85317c226a17beb8fcced4f7464c9cd98b1a9f5454f189d6a5e41da42f1b52183dfe66f166371e9caafb80f170af967d8c7b8999fecd6751c0b","sizeBytes":184,"signature":"73db42e6419b8c7b628e73c87229c182557c258a4ec4ed8a270cb01658fbf7b8d1289288d543bf6a8ec85c9f3836ef8d70f7cba18b38604b128b3973d5bcd009"},{"path":"dist/index.cjs","hash":"05d0651e0f60339fd965c267348246b556fb8ad66691da5d3638762e5706942d4d013f7ed1b6d7ea05855a57d8e1b766b32a43f78f88ca77bfe73e78754114e4","sizeBytes":48540,"signature":"30aacc4fa112e368009ff314a0be6c81a089973ddfe83776753edba1e13f33e1ef4d34f1a92385c8fd6d57dac0d852c8aafd1787dd5f8d0b2bfd4cafc9791c06"},{"path":"dist/index.d.ts","hash":"156c75711d80b547ddfa759c9d67e7bdba8de383ee092b396c88ca8cde796d070bd39df7cc303939be1f1692746867b6358ca2d6e7d4293110f0e99404c9bc15","sizeBytes":6173,"signature":"2e626744ce8fe5eb6bfaed6c35aa86078af4cf493125669bcc0743b441e785f5092e3940659cac8102146e1e5ffdbe6ba82d4839e4ba74d86ce76488a4d47105"},{"path":"dist/index.js","hash":"07f5d52076c39fafb430344efbf45d298e56e3e672225d7d308fb516bcaed879d53651bb6a52452b568d750c27790590724cba883f16c36bbdcb25eae5fa295a","sizeBytes":47250,"signature":"2e543f57c15db87d8f8b440c9ebd6f9afae2949fd53f231965026eef59104ab8fa2687db938ed5401c74f9790198a011ae0f15ef1e869de5deae219e9436ba08"},{"path":"package.json","hash":"96dc001e5b9cdd99d1b87aaf49e4f3016298c265ca38e81cf64c0222ff06f59bec18ccc054d0995fbb671d4510f3e71db67fc84093d56ebd9c11de096fa3b06e","sizeBytes":1352,"signature":"7455584d3922864e9f444ced6421755d38c601a318ae51c086ff3d3d28554800369560bed6ceea3850bdf83efbbb1000e2471d43b13f7fd3245f27db8529670a"}]}

Sorry, the diff of this file is not supported yet