Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions keep-ui/app/(keep)/providers/provider-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import { KeepApiError, KeepApiReadOnlyError } from "@/shared/api";
import { showErrorToast } from "@/shared/ui";
import {
base64urlencode,
generatePkceVerifier,
generateRandomString,
sha256,
} from "@/shared/lib/encodings";
Expand Down Expand Up @@ -103,7 +104,7 @@ function getInitialFormValues(provider: Provider, isHealthCheck?: boolean) {
const initialValues: ProviderFormData = {
provider_id: provider.id,
install_webhook: !isHealthCheck
? provider.can_setup_webhook ?? false
? (provider.can_setup_webhook ?? false)
: false,
pulling_enabled: provider.pulling_enabled,
};
Expand Down Expand Up @@ -205,7 +206,7 @@ const ProviderForm = ({
const callInstallWebhook = async () => await installWebhook(provider);

async function handleOauth() {
const verifier = generateRandomString();
const verifier = generatePkceVerifier();
cookieCutter.set("verifier", verifier);
cookieCutter.set(
"oauth2_install_webhook",
Expand Down
34 changes: 26 additions & 8 deletions keep-ui/shared/lib/encodings.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Converts a decimal number to a hexadecimal string with proper padding
*
*
* @param dec - The decimal number to convert
* @returns A hexadecimal string representation
* @internal This is a utility function used by generateRandomString
Expand All @@ -11,9 +11,9 @@ function dec2hex(dec: number) {

/**
* Generates a cryptographically secure random string
*
*
* @returns A random hexadecimal string of 56 characters
*
*
* @example
* const randomStr = generateRandomString();
* // e.g. "7b8d4f2e9a1c6b3d5e8f2a7c9b4d1e6f3a8c5b2d7e9f1a3c8b6d4e7f2a9c5"
Expand All @@ -24,12 +24,30 @@ export function generateRandomString() {
return Array.from(array, dec2hex).join("");
}

/**
* Generates a PKCE verifier string with length 128 characters
*
* @returns a random string of 128 characters
*
* @example
* const verifier = generatePkceVerifier();
* // e.g. "7b8d4f2e9a1c6b3d5e8f2a7c9b4d1e6f3a8c5b2d7e9f1a3c8b6d4e7f2a9c5"
*/
export function generatePkceVerifier(): string {
const arr = new Uint8Array(96);
window.crypto.getRandomValues(arr);
return btoa(String.fromCharCode(...arr))
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=+$/, "");
}

/**
* Computes the SHA-256 hash of a string
*
*
* @param plain - The input string to hash
* @returns A Promise that resolves to an ArrayBuffer containing the hash
*
*
* @example
* const hashBuffer = await sha256("hello world");
*/
Expand All @@ -41,15 +59,15 @@ export function sha256(plain: string) {

/**
* Encodes an ArrayBuffer to base64url format (URL-safe base64)
*
*
* Base64url encoding is a variant of base64 that is URL and filename safe:
* - Replaces '+' with '-'
* - Replaces '/' with '_'
* - Removes padding '=' characters
*
*
* @param a - The ArrayBuffer to encode
* @returns The base64url-encoded string
*
*
* @example
* const hashBuffer = await sha256("hello world");
* const base64urlStr = base64urlencode(hashBuffer);
Expand Down