Skip to content

Commit 769522b

Browse files
fix: normalized the password check
1 parent 16b5c49 commit 769522b

File tree

5 files changed

+67
-36
lines changed

5 files changed

+67
-36
lines changed

src/utils/codecs/crockford-base32.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,21 @@ function encode(input: Uint8Array) {
6868
return output.map((byte) => c32[byte]).join("");
6969
}
7070

71+
export function splitBase32(input: string): string {
72+
const middle = Math.floor(input.length / 2);
73+
const quart = Math.floor(middle / 2);
74+
const secondQuart = middle + Math.floor((input.length - middle) / 2);
75+
return (
76+
input.substring(0, quart) +
77+
"-" +
78+
input.substring(quart, middle) +
79+
"-" +
80+
input.substring(middle, secondQuart) +
81+
"-" +
82+
input.substring(secondQuart)
83+
);
84+
}
85+
7186
export function sanitizeCrockfordBase32(
7287
input: string,
7388
ignoreUnknown: true,
@@ -85,16 +100,13 @@ export function sanitizeCrockfordBase32(input: string, ignoreUnknown: boolean) {
85100
continue;
86101
}
87102
if (validChar !== undefined) {
88-
if (count % 5 === 0 && count !== 0) {
89-
sane += "-";
90-
}
91103
count += 1;
92104
sane += c32[validChar];
93105
} else if (!ignoreUnknown) {
94106
return null;
95107
}
96108
}
97-
return sane;
109+
return splitBase32(sane);
98110
}
99111

100112
function decode(input: string) {

src/utils/crypto.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,17 @@ export interface PasswordGenerator {
122122
entropyNeeded: number;
123123
entropyProvided: number;
124124
getRandom(random: RandomSource): string;
125+
getPossiblePassword(input: string): string | undefined;
126+
}
127+
128+
export function getPossibleWordsPassword(input: string, size: number) {
129+
if (input.length !== size) {
130+
return undefined;
131+
}
132+
if (!/^[a-z-]+$/.test(input)) {
133+
return undefined;
134+
}
135+
return input;
125136
}
126137

127138
export class RandomWords implements PasswordGenerator {
@@ -154,6 +165,10 @@ export class RandomWords implements PasswordGenerator {
154165
this.entropyProvided = this.weighted.entropyProvided;
155166
}
156167

168+
getPossiblePassword(input: string): string | undefined {
169+
return getPossibleWordsPassword(input, this.targetLength);
170+
}
171+
157172
getRandom(random: RandomSource): string {
158173
return this.weighted
159174
.getRandom(random)

src/utils/password-base32.ts

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
1-
import { crockfordBase32 } from "@/utils/codecs/crockford-base32";
1+
import {
2+
crockfordBase32,
3+
sanitizeCrockfordBase32,
4+
splitBase32,
5+
} from "@/utils/codecs/crockford-base32";
26
import type { PasswordGenerator, RandomSource } from "@/utils/crypto";
37

48
function toReadableHash(input: Uint8Array) {
59
const c = crockfordBase32.encode(input);
6-
const middle = Math.floor(c.length / 2);
7-
const quart = Math.floor(middle / 2);
8-
const secondQuart = middle + Math.floor((c.length - middle) / 2);
9-
return (
10-
c.substring(0, quart) +
11-
"-" +
12-
c.substring(quart, middle) +
13-
"-" +
14-
c.substring(middle, secondQuart) +
15-
"-" +
16-
c.substring(secondQuart)
17-
);
10+
return splitBase32(c);
11+
}
12+
13+
export function getPossibleBase32Password(
14+
input: string,
15+
size: number,
16+
): string | undefined {
17+
const key = sanitizeCrockfordBase32(input, false);
18+
if (!key) {
19+
return undefined;
20+
}
21+
if (key.length !== size) {
22+
return undefined;
23+
}
24+
return key;
1825
}
1926

2027
class RandomBase32 implements PasswordGenerator {
@@ -35,6 +42,10 @@ class RandomBase32 implements PasswordGenerator {
3542
this.entropyProvided = bits;
3643
}
3744

45+
getPossiblePassword(input: string): string | undefined {
46+
return getPossibleBase32Password(input, this.targetLength);
47+
}
48+
3849
getRandom(random: RandomSource) {
3950
return toReadableHash(random.getBytes(this.buffer));
4051
}

src/utils/password-generators.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
import { passwordBase32 } from "@/utils/password-base32";
22
import { passwordWords } from "@/utils/password-dict-words";
3+
import type { PasswordGenerator } from "./crypto";
34

4-
export const passwordGenerators = [passwordBase32, passwordWords];
5+
export const passwordGenerators: PasswordGenerator[] = [
6+
passwordBase32,
7+
passwordWords,
8+
];

src/utils/safeDoc.ts

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type {
1111
} from "@/utils/codecs";
1212
import { codecs } from "@/utils/codecs";
1313
import { uniqueRequests } from "@/utils/requests";
14+
import { passwordGenerators } from "./password-generators";
1415

1516
export {
1617
createDocCodec,
@@ -91,25 +92,13 @@ export async function toPublicKey(privateKey: string) {
9192
);
9293
}
9394

94-
export function getPossibleDocKey(input: string) {
95-
return getPossibleBase32Key(input) ?? getPossibleWordsKey(input);
96-
}
97-
98-
function getPossibleWordsKey(input: string) {
99-
if (/^[a-z-]{38}/.test(input)) {
100-
return input;
101-
}
102-
}
103-
104-
function getPossibleBase32Key(input: string) {
105-
const key = sanitizeCrockfordBase32(input, false);
106-
if (!key) {
107-
return undefined;
108-
}
109-
if (key.length !== 23) {
110-
return undefined;
95+
export function getPossibleDocKey(input: string): string | undefined {
96+
for (const generator of passwordGenerators) {
97+
const key = generator.getPossiblePassword(input);
98+
if (key !== undefined) {
99+
return key;
100+
}
111101
}
112-
return key;
113102
}
114103

115104
export interface ParsedDocument<

0 commit comments

Comments
 (0)