Make 1 the minimum registration ID
This commit is contained in:
parent
e20ec013f5
commit
5219cdf2c9
4 changed files with 30 additions and 26 deletions
28
ts/Crypto.ts
28
ts/Crypto.ts
|
@ -34,17 +34,8 @@ export type EncryptedAttachment = {
|
||||||
digest: Uint8Array;
|
digest: Uint8Array;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generate a number between zero and 16383
|
|
||||||
export function generateRegistrationId(): number {
|
export function generateRegistrationId(): number {
|
||||||
const bytes = getRandomBytes(2);
|
return randomInt(1, 16383);
|
||||||
const id = new Uint16Array(
|
|
||||||
bytes.buffer,
|
|
||||||
bytes.byteOffset,
|
|
||||||
bytes.byteLength / 2
|
|
||||||
)[0];
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-bitwise
|
|
||||||
return id & 0x3fff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deriveStickerPackKey(packKey: Uint8Array): Uint8Array {
|
export function deriveStickerPackKey(packKey: Uint8Array): Uint8Array {
|
||||||
|
@ -342,16 +333,6 @@ export function sha256(data: Uint8Array): Uint8Array {
|
||||||
|
|
||||||
// Utility
|
// Utility
|
||||||
|
|
||||||
export function getRandomValue(low: number, high: number): number {
|
|
||||||
const diff = high - low;
|
|
||||||
const bytes = getRandomBytes(1);
|
|
||||||
|
|
||||||
// Because high and low are inclusive
|
|
||||||
const mod = diff + 1;
|
|
||||||
|
|
||||||
return (bytes[0] % mod) + low;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getZeroes(n: number): Uint8Array {
|
export function getZeroes(n: number): Uint8Array {
|
||||||
return new Uint8Array(n);
|
return new Uint8Array(n);
|
||||||
}
|
}
|
||||||
|
@ -683,6 +664,13 @@ export function decrypt(
|
||||||
return crypto.decrypt(...args);
|
return crypto.decrypt(...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate an integer between `min` and `max`, inclusive.
|
||||||
|
*/
|
||||||
|
export function randomInt(min: number, max: number): number {
|
||||||
|
return crypto.randomInt(min, max + 1);
|
||||||
|
}
|
||||||
|
|
||||||
export function getRandomBytes(size: number): Uint8Array {
|
export function getRandomBytes(size: number): Uint8Array {
|
||||||
return crypto.getRandomBytes(size);
|
return crypto.getRandomBytes(size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,6 +119,10 @@ export class Crypto {
|
||||||
return Buffer.concat([decipher.update(input), decipher.final()]);
|
return Buffer.concat([decipher.update(input), decipher.final()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public randomInt(min: number, max: number): number {
|
||||||
|
return crypto.randomInt(min, max);
|
||||||
|
}
|
||||||
|
|
||||||
public getRandomBytes(size: number): Uint8Array {
|
public getRandomBytes(size: number): Uint8Array {
|
||||||
return crypto.randomBytes(size);
|
return crypto.randomBytes(size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import {
|
||||||
decryptSymmetric,
|
decryptSymmetric,
|
||||||
hmacSha256,
|
hmacSha256,
|
||||||
verifyHmacSha256,
|
verifyHmacSha256,
|
||||||
|
randomInt,
|
||||||
uuidToBytes,
|
uuidToBytes,
|
||||||
bytesToUuid,
|
bytesToUuid,
|
||||||
} from '../Crypto';
|
} from '../Crypto';
|
||||||
|
@ -164,11 +165,11 @@ describe('Crypto', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('generateRegistrationId', () => {
|
describe('generateRegistrationId', () => {
|
||||||
it('generates an integer between 0 and 16383 (inclusive)', () => {
|
it('generates an integer between 1 and 16383 (inclusive)', () => {
|
||||||
let max = 0;
|
let max = -1;
|
||||||
for (let i = 0; i < 100; i += 1) {
|
for (let i = 0; i < 100; i += 1) {
|
||||||
const id = generateRegistrationId();
|
const id = generateRegistrationId();
|
||||||
assert.isAtLeast(id, 0);
|
assert.isAtLeast(id, 1);
|
||||||
assert.isAtMost(id, 16383);
|
assert.isAtMost(id, 16383);
|
||||||
assert(Number.isInteger(id));
|
assert(Number.isInteger(id));
|
||||||
|
|
||||||
|
@ -441,6 +442,17 @@ describe('Crypto', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('randomInt', () => {
|
||||||
|
it('returns random integers in a range (inclusive)', () => {
|
||||||
|
const seen = new Set<number>();
|
||||||
|
for (let i = 0; i < 1_000_000 || seen.size < 3; i += 1) {
|
||||||
|
seen.add(randomInt(1, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.deepStrictEqual(seen, new Set([1, 2, 3]));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('uuidToBytes', () => {
|
describe('uuidToBytes', () => {
|
||||||
it('converts valid UUIDs to Uint8Arrays', () => {
|
it('converts valid UUIDs to Uint8Arrays', () => {
|
||||||
const expectedResult = new Uint8Array([
|
const expectedResult = new Uint8Array([
|
||||||
|
|
|
@ -35,7 +35,7 @@ import type { UUID, UUIDStringType } from '../types/UUID';
|
||||||
import { UUIDKind } from '../types/UUID';
|
import { UUIDKind } from '../types/UUID';
|
||||||
import type { DirectoryConfigType } from '../types/RendererConfig';
|
import type { DirectoryConfigType } from '../types/RendererConfig';
|
||||||
import * as Bytes from '../Bytes';
|
import * as Bytes from '../Bytes';
|
||||||
import { getRandomValue } from '../Crypto';
|
import { randomInt } from '../Crypto';
|
||||||
import * as linkPreviewFetch from '../linkPreviews/linkPreviewFetch';
|
import * as linkPreviewFetch from '../linkPreviews/linkPreviewFetch';
|
||||||
import { isBadgeImageFileUrlValid } from '../badges/isBadgeImageFileUrlValid';
|
import { isBadgeImageFileUrlValid } from '../badges/isBadgeImageFileUrlValid';
|
||||||
|
|
||||||
|
@ -2431,11 +2431,11 @@ export function initialize({
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHeaderPadding() {
|
function getHeaderPadding() {
|
||||||
const max = getRandomValue(1, 64);
|
const max = randomInt(1, 64);
|
||||||
let characters = '';
|
let characters = '';
|
||||||
|
|
||||||
for (let i = 0; i < max; i += 1) {
|
for (let i = 0; i < max; i += 1) {
|
||||||
characters += String.fromCharCode(getRandomValue(65, 122));
|
characters += String.fromCharCode(randomInt(65, 122));
|
||||||
}
|
}
|
||||||
|
|
||||||
return characters;
|
return characters;
|
||||||
|
|
Loading…
Reference in a new issue