mirror of
https://codeberg.org/MarkusThielker/next-ory.git
synced 2025-04-18 00:21:18 +00:00
NORY-46: add dynamic redirect_uri input
This commit is contained in:
parent
edbb93c03b
commit
ce28973dea
2 changed files with 72 additions and 19 deletions
|
@ -14,6 +14,7 @@ import { AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle }
|
||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import { Checkbox } from '@/components/ui/checkbox';
|
import { Checkbox } from '@/components/ui/checkbox';
|
||||||
|
import { Minus } from 'lucide-react';
|
||||||
|
|
||||||
interface CreateClientFormProps {
|
interface CreateClientFormProps {
|
||||||
action: (data: z.infer<typeof clientFormSchema>) => Promise<AxiosResponse<OAuth2Client, any>>;
|
action: (data: z.infer<typeof clientFormSchema>) => Promise<AxiosResponse<OAuth2Client, any>>;
|
||||||
|
@ -22,17 +23,19 @@ interface CreateClientFormProps {
|
||||||
export function CreateClientForm({ action }: CreateClientFormProps) {
|
export function CreateClientForm({ action }: CreateClientFormProps) {
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const [redirectUris, setRedirectUris] = useState<string[]>(['']);
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof clientFormSchema>>({
|
const form = useForm<z.infer<typeof clientFormSchema>>({
|
||||||
resolver: zodResolver(clientFormSchema),
|
resolver: zodResolver(clientFormSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
client_name: '',
|
client_name: '',
|
||||||
owner: '',
|
|
||||||
scope: '',
|
scope: '',
|
||||||
|
redirect_uris: [''],
|
||||||
skip: false,
|
skip: false,
|
||||||
logo_uri: '',
|
logo_uri: '',
|
||||||
policy_uri: '',
|
policy_uri: '',
|
||||||
tos_uri: '',
|
tos_uri: '',
|
||||||
|
owner: '',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -53,6 +56,23 @@ export function CreateClientForm({ action }: CreateClientFormProps) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const addRedirectUri = () => {
|
||||||
|
setRedirectUris([...redirectUris, '']);
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeRedirectUri = (index) => {
|
||||||
|
const updatedRedirectUris = redirectUris.filter((_, i) => i !== index);
|
||||||
|
setRedirectUris(updatedRedirectUris);
|
||||||
|
form.setValue('redirect_uris', updatedRedirectUris);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleInputChange = (index, event) => {
|
||||||
|
const updatedRedirectUris = [...redirectUris];
|
||||||
|
updatedRedirectUris[index] = event.target.value;
|
||||||
|
setRedirectUris(updatedRedirectUris);
|
||||||
|
form.setValue('redirect_uris', updatedRedirectUris);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{
|
{
|
||||||
|
@ -117,27 +137,44 @@ export function CreateClientForm({ action }: CreateClientFormProps) {
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<FormField
|
{redirectUris.map((uri, index) => (
|
||||||
control={form.control}
|
<div key={index} className="mb-4">
|
||||||
name="scope"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Scopes</FormLabel>
|
<FormLabel htmlFor={`redirect_uri-${index}`}>Redirect
|
||||||
|
URI {index + 1}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input placeholder="post:read post:write user:read" {...field} />
|
<div className="relative">
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
id={`redirect_uri-${index}`}
|
||||||
|
value={uri}
|
||||||
|
placeholder="https://"
|
||||||
|
className="pr-10"
|
||||||
|
{...form.register(`redirect_uris.${index}`)}
|
||||||
|
onChange={(event) => handleInputChange(index, event)}
|
||||||
|
/>
|
||||||
|
{redirectUris.length > 1 && (
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
size="icon"
|
||||||
|
variant="destructive"
|
||||||
|
className="absolute inset-y-0 right-0 rounded-l-none"
|
||||||
|
onClick={() => removeRedirectUri(index)}>
|
||||||
|
<Minus/>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormDescription>
|
{form.errors?.redirect_uris && form.errors.redirect_uris[index] && (
|
||||||
Scope is a string containing a space-separated list of scope values (as
|
<FormMessage>{form.errors.redirect_uris[index].message}</FormMessage>
|
||||||
described in
|
)}
|
||||||
Section 3.3 of OAuth 2.0 [RFC6749]) that the client can use when
|
|
||||||
requesting
|
|
||||||
access
|
|
||||||
tokens.
|
|
||||||
</FormDescription>
|
|
||||||
<FormMessage/>
|
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
</div>
|
||||||
/>
|
))}
|
||||||
|
|
||||||
|
<Button type="button" onClick={addRedirectUri}>
|
||||||
|
Add Redirect URI
|
||||||
|
</Button>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
@ -162,6 +199,7 @@ export function CreateClientForm({ action }: CreateClientFormProps) {
|
||||||
</FormDescription>
|
</FormDescription>
|
||||||
</div>
|
</div>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
|
{/* TODO: change to switch */}
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={field.value}
|
checked={field.value}
|
||||||
onCheckedChange={field.onChange}
|
onCheckedChange={field.onChange}
|
||||||
|
@ -255,6 +293,20 @@ export function CreateClientForm({ action }: CreateClientFormProps) {
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle>
|
||||||
|
Supported OAuth2 flows
|
||||||
|
</CardTitle>
|
||||||
|
<CardDescription>
|
||||||
|
Configure allowed grant types and response types for this OAuth2 Client.
|
||||||
|
</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
<div className="space-x-2">
|
<div className="space-x-2">
|
||||||
<Button type="button" variant="outline" onClick={() => {
|
<Button type="button" variant="outline" onClick={() => {
|
||||||
router.back();
|
router.back();
|
||||||
|
|
|
@ -3,10 +3,11 @@ import { z } from 'zod';
|
||||||
export const clientFormSchema = z.object({
|
export const clientFormSchema = z.object({
|
||||||
access_token_strategy: z.string().default('opaque').readonly(),
|
access_token_strategy: z.string().default('opaque').readonly(),
|
||||||
client_name: z.string().min(1, 'Client name is required'),
|
client_name: z.string().min(1, 'Client name is required'),
|
||||||
owner: z.string().min(1, 'Owner is required'),
|
|
||||||
scope: z.string(),
|
scope: z.string(),
|
||||||
|
redirect_uris: z.array(z.string().url({ message: 'Invalid URL' })).min(1, { message: 'At least one redirect URI is required' }),
|
||||||
skip: z.boolean(),
|
skip: z.boolean(),
|
||||||
logo_uri: z.string().url(),
|
logo_uri: z.string().url(),
|
||||||
tos_uri: z.string().url(),
|
tos_uri: z.string().url(),
|
||||||
policy_uri: z.string().url(),
|
policy_uri: z.string().url(),
|
||||||
|
owner: z.string().min(1, 'Owner is required'),
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue