Skip to content

Commit

Permalink
Fix API key redirect URL on in-app wallet settings and unresponsive g…
Browse files Browse the repository at this point in the history
…eneral project settings page
  • Loading branch information
MananTank committed Dec 16, 2024
1 parent 6994310 commit 3f5fec7
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ import { type FieldArrayWithId, useFieldArray } from "react-hook-form";
import { toast } from "sonner";
import { joinWithComma, toArrFromList } from "utils/string";
import {
type ApiKeyValidationSchema,
HIDDEN_SERVICES,
apiKeyValidationSchema,
type ProjectSettingsPageFormSchema,
projectSettingsPageFormSchema,
} from "../../../../../components/settings/ApiKeys/validations";

type EditProjectUIPaths = {
Expand Down Expand Up @@ -86,16 +86,16 @@ interface EditApiKeyProps {
showNebulaSettings: boolean;
}

type UpdateAPIForm = UseFormReturn<ApiKeyValidationSchema>;
type UpdateAPIForm = UseFormReturn<ProjectSettingsPageFormSchema>;

export const ProjectGeneralSettingsPageUI: React.FC<EditApiKeyProps> = (
props,
) => {
const { apiKey, updateMutation, deleteMutation } = props;
const trackEvent = useTrack();
const router = useDashboardRouter();
const form = useForm<ApiKeyValidationSchema>({
resolver: zodResolver(apiKeyValidationSchema),
const form = useForm<ProjectSettingsPageFormSchema>({
resolver: zodResolver(projectSettingsPageFormSchema),
defaultValues: {
name: apiKey.name,
domains: joinWithComma(apiKey.domains),
Expand Down Expand Up @@ -484,7 +484,7 @@ function EnabledServicesSetting(props: {
});
const handleAction = (
srvIdx: number,
srv: FieldArrayWithId<ApiKeyValidationSchema, "services", "id">,
srv: FieldArrayWithId<ProjectSettingsPageFormSchema, "services", "id">,
actionName: string,
checked: boolean,
) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,10 @@ function AuthEndpointFields(props: {
name: "customAuthEndpoint.customHeaders",
});

const expandCustomAuthEndpointField =
form.watch("customAuthEndpoint")?.authEndpoint !== undefined &&
canEditAdvancedFeatures;

return (
<div>
<SwitchContainer
Expand All @@ -445,9 +449,7 @@ function AuthEndpointFields(props: {
>
<GatedSwitch
trackingLabel="customAuthEndpoint"
checked={
!!form.watch("customAuthEndpoint") && canEditAdvancedFeatures
}
checked={expandCustomAuthEndpointField}
upgradeRequired={!canEditAdvancedFeatures}
onCheckedChange={(checked) => {
form.setValue(
Expand All @@ -464,7 +466,7 @@ function AuthEndpointFields(props: {
</SwitchContainer>

<AdvancedConfigurationContainer
show={canEditAdvancedFeatures && !!form.watch("customAuthEndpoint")}
show={expandCustomAuthEndpointField}
className="grid grid-cols-1 gap-6 lg:grid-cols-2"
>
<FormField
Expand Down
65 changes: 48 additions & 17 deletions apps/dashboard/src/components/settings/ApiKeys/validations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const nameValidation = z
const domainsValidation = z.string().refine(
(str) =>
validStrList(str, (domain) => {
return domain.split(":")[0] === "localhost" || RE_DOMAIN.test(domain);
return domain.startsWith("localhost:") || RE_DOMAIN.test(domain);
}),
{
message: "Some of the domains are invalid",
Expand Down Expand Up @@ -95,26 +95,55 @@ export const apiKeyCreateValidationSchema = z.object({
services: servicesValidation,
});

export const apiKeyValidationSchema = z.object({
function isValidRedirectURI(uri: string) {
// whitespace is not allowed
if (/\s/g.test(uri)) {
return false;
}

// foo://... is allowed
if (uri.includes("://")) {
return true;
}

// localhost:... is allowed
if (uri.startsWith("localhost:")) {
return true;
}

// valid url is allowed
try {
new URL(uri);
return true;
} catch {
// invalid
}

// everything else is invalid
return false;
}

const redirectUriSchema = z
.string()
.refine((str) => validStrList(str, isValidRedirectURI), {
message:
"Some of the redirect URIs are invalid. Make sure they are valid URIs and do not contain spaces.",
})
.refine((str) => str !== "*", {
message: "Wildcard redirect URIs are not allowed",
});

// TODO: move this schema to project settings folder in separate PR
export const projectSettingsPageFormSchema = z.object({
name: nameValidation,
domains: domainsValidation,
services: servicesValidation,
bundleIds: z.string().refine((str) => validStrList(str, RE_BUNDLE_ID), {
message: "Some of the bundle ids are invalid",
}),
redirectUrls: z
.string()
.refine(
(str) =>
validStrList(str, (url) => url.includes("://") && !/\s/g.test(url)),
{
message:
"Some of the redirect URIs are invalid. Make sure they are valid URIs and do not contain spaces.",
},
)
.refine((str) => str !== "*", {
message: "Wildcard redirect URIs are not allowed",
}),
// no strict validation for redirectUrls, because project general page does not render redirectUrls form field
// so if the user has already saved an invalid `redirectUrls` on in-app wallet project settings page ( which is fixed now ) - it won't prevent them from updating the general project settings
redirectUrls: z.string(),
});

export const apiKeyEmbeddedWalletsValidationSchema = z.object({
Expand All @@ -127,7 +156,7 @@ export const apiKeyEmbeddedWalletsValidationSchema = z.object({
applicationImageUrl: applicationImageUrlValidation,
}),
]),
redirectUrls: z.union([z.undefined(), z.string()]),
redirectUrls: redirectUriSchema,
});

export const apiKeyPayConfigValidationSchema = z.object({
Expand All @@ -138,7 +167,9 @@ export type ApiKeyCreateValidationSchema = z.infer<
typeof apiKeyCreateValidationSchema
>;

export type ApiKeyValidationSchema = z.infer<typeof apiKeyValidationSchema>;
export type ProjectSettingsPageFormSchema = z.infer<
typeof projectSettingsPageFormSchema
>;

export type ApiKeyEmbeddedWalletsValidationSchema = z.infer<
typeof apiKeyEmbeddedWalletsValidationSchema
Expand Down

0 comments on commit 3f5fec7

Please sign in to comment.