Skip to content

Commit 8439211

Browse files
Merge branch 'develop'
2 parents 4753d14 + 0dd25a9 commit 8439211

File tree

6 files changed

+38
-12
lines changed

6 files changed

+38
-12
lines changed

eslint.config.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,14 @@ module.exports = defineConfig([
3939

4040
"import/resolver": {
4141
node: {
42-
paths: ["src"],
43-
extensions: [".js", ".jsx", ".ts"],
42+
// allow resolving absolute imports from package src folders
43+
paths: ["src", "packages/app/src", "packages/native-components-lib/src", "packages/*/src"],
44+
extensions: [".js", ".jsx", ".ts", ".tsx", ".json"],
45+
},
46+
typescript: {
47+
project: ["./packages/app/tsconfig.json", "./packages/native-components-lib/tsconfig.json"],
48+
extensions: [".js", ".jsx", ".ts", ".tsx"],
49+
alwaysTryTypes: true,
4450
},
4551
},
4652
},

packages/app/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
"@vitejs/plugin-react": "^5.1.2",
4545
"@vitest/coverage-v8": "^4.0.15",
4646
"eslint": "^9.39.1",
47+
"eslint-import-resolver-typescript": "^3.5.0",
4748
"eslint-config-prettier": "^10.1.8",
4849
"eslint-plugin-import": "^2.32.0",
4950
"eslint-plugin-jsx-a11y": "^6.10.2",
@@ -80,4 +81,4 @@
8081
"last 1 safari version"
8182
]
8283
}
83-
}
84+
}

packages/app/src/hooks/useTheme.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useEffect, useState } from "react";
33

44
type Theme = "light" | "dark";
55

6-
export function useTheme(): { theme: Theme; toggleTheme: () => void; setTheme: (theme: Theme) => void } {
6+
export function useTheme(): { theme: Theme; toggleTheme: () => void; setTheme: (newTheme: Theme) => void } {
77
// Initialize theme with localStorage or default to "light"
88
const [theme, setThemeState] = useState<Theme>(() => {
99
const savedTheme = localStorage.getItem("theme");

packages/app/src/services/passwords.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,25 @@ const CHAR_SETS = {
2929
symbols: "!@#$%^&*",
3030
};
3131

32+
// Returns a cryptographically secure random integer in [0, max)
33+
function getSecureRandomInt(max: number): number {
34+
if (max <= 0 || max > Number.MAX_SAFE_INTEGER) {
35+
throw new Error("Invalid max value for random integer");
36+
}
37+
// Range is [0, max)
38+
const rand = new Uint32Array(1);
39+
let x;
40+
// Avoid bias: only accept numbers < rangeLimit
41+
// rangeLimit = Math.floor(2**32 / max) * max;
42+
// see https://stackoverflow.com/a/78239136 for explanation
43+
const rangeLimit = Math.floor(0x100000000 / max) * max;
44+
do {
45+
window.crypto.getRandomValues(rand);
46+
x = rand[0];
47+
} while (x >= rangeLimit);
48+
return x % max;
49+
}
50+
3251
function removeAmbiguous(charset: string): string {
3352
return charset
3453
.split("")
@@ -37,7 +56,7 @@ function removeAmbiguous(charset: string): string {
3756
}
3857

3958
function getRandomChar(charset: string): string {
40-
const index = Math.floor(Math.random() * charset.length);
59+
const index = getSecureRandomInt(charset.length);
4160
return charset[index];
4261
}
4362

@@ -92,7 +111,7 @@ const generatePassword = (settings: PasswordConfiguration): string => {
92111

93112
// Shuffle the final password
94113
for (let i = guaranteedChars.length - 1; i > 0; i--) {
95-
const j = Math.floor(Math.random() * (i + 1));
114+
const j = getSecureRandomInt(i + 1);
96115
[guaranteedChars[i], guaranteedChars[j]] = [guaranteedChars[j], guaranteedChars[i]];
97116
}
98117

packages/app/src/setupTests.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
// expect(element).toHaveTextContent(/react/i)
44
// learn more: https://github.com/testing-library/jest-dom
55
import "@testing-library/jest-dom/vitest";
6-
import configJson from "../public/config";
6+
import configJson from "../public/config.json";
77

88
window.env = configJson;

packages/app/src/utilities/requests.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ const requestEntity = (url: string) => {
44
return secureApiFetch(url, { method: "GET" });
55
};
66

7-
const requestEntities = (url: string, params?: Record<string, any>) => {
7+
const requestEntities = (url: string, params?: Record<string, string>) => {
88
const fullUrl = url + (params ? "?" + new URLSearchParams(params).toString() : "");
99
return secureApiFetch(fullUrl, { method: "GET" });
1010
};
1111

12-
const requestEntityPost = (url: string, data?: FormData | Record<string, any>) => {
13-
const params: Record<string, any> = {
12+
const requestEntityPost = (url: string, data?: FormData | Record<string, string>) => {
13+
const params: Record<string, string | FormData | { "Content-Type": string }> = {
1414
method: "POST",
1515
};
1616
if (data) {
@@ -27,7 +27,7 @@ const requestEntityPost = (url: string, data?: FormData | Record<string, any>) =
2727
return secureApiFetch(url, params);
2828
};
2929

30-
const requestEntityPut = (url: string, data: any) => {
30+
const requestEntityPut = (url: string, data: Record<string, string>) => {
3131
return secureApiFetch(url, {
3232
method: "PUT",
3333
body: JSON.stringify(data),
@@ -37,7 +37,7 @@ const requestEntityPut = (url: string, data: any) => {
3737
});
3838
};
3939

40-
const requestEntityPatch = (url: string, data: any) => {
40+
const requestEntityPatch = (url: string, data: Record<string, string>) => {
4141
return secureApiFetch(url, {
4242
method: "PATCH",
4343
body: JSON.stringify(data),

0 commit comments

Comments
 (0)