Compare commits
8 Commits
e1e0532fdf
...
7b4f7dff0c
Author | SHA1 | Date | |
---|---|---|---|
|
7b4f7dff0c | ||
db9a6a1b83 | |||
b6db72a5b7 | |||
f0bfa90140 | |||
809da23b91 | |||
054e1c6da0 | |||
4d576b07da | |||
d085a2ab19 |
@ -1,30 +1,28 @@
|
|||||||
/* Copyright (C) 2024 Manuel Bustillo*/
|
/* Copyright (C) 2024 Manuel Bustillo*/
|
||||||
|
|
||||||
'use client';
|
'use client';
|
||||||
import Link from 'next/link';
|
|
||||||
import styles from '@/app/ui/home.module.css';
|
|
||||||
import LoginForm from '@/app/ui/components/login-form';
|
import LoginForm from '@/app/ui/components/login-form';
|
||||||
|
import RegistrationForm from '@/app/ui/components/registration-form';
|
||||||
|
import { useParams } from 'next/navigation'
|
||||||
|
|
||||||
|
export default async function Page() {
|
||||||
|
const params = useParams<{ slug: string }>()
|
||||||
|
localStorage.setItem('slug', await params.slug);
|
||||||
|
|
||||||
|
|
||||||
export default async function Page({ params }: { params: Promise<{ slug: string }> }) {
|
|
||||||
|
|
||||||
localStorage.setItem('slug', (await params).slug)
|
|
||||||
return (
|
return (
|
||||||
<main className="flex min-h-screen flex-col p-6">
|
<main className="flex min-h-screen flex-col p-6">
|
||||||
<div className="flex flex-row">
|
<div className="flex flex-row">
|
||||||
<div className="w-1/2">
|
<div className="w-1/2">
|
||||||
|
|
||||||
Already have an account? Sign in
|
Already have an account? Sign in
|
||||||
|
|
||||||
<LoginForm />
|
<LoginForm />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="w-1/2">
|
<div className="w-1/2">
|
||||||
Don't have an account? Register now!
|
Don't have an account? Register now!
|
||||||
|
<RegistrationForm />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
/* Copyright (C) 2024 Manuel Bustillo*/
|
/* Copyright (C) 2024 Manuel Bustillo*/
|
||||||
|
|
||||||
import { getCsrfToken, getSlug } from '@/app/lib/utils';
|
import { asArray, getCsrfToken, getSlug } from '@/app/lib/utils';
|
||||||
import { User } from '@/app/lib/definitions';
|
import { Captcha, StructuredErrors, User } from '@/app/lib/definitions';
|
||||||
|
|
||||||
export function login({ email, password, onLogin }: { email: string, password: string, onLogin: (user: User) => void }) {
|
export function login({ email, password, onLogin }: { email: string, password: string, onLogin: (user: User) => void }) {
|
||||||
console.log(email, password);
|
|
||||||
return fetch(`/api/${getSlug()}/users/sign_in`, {
|
return fetch(`/api/${getSlug()}/users/sign_in`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({ user: { email, password } }),
|
body: JSON.stringify({ user: { email, password } }),
|
||||||
@ -34,3 +33,45 @@ export function logout({ onLogout }: { onLogout: () => void }) {
|
|||||||
}).then(onLogout)
|
}).then(onLogout)
|
||||||
.catch((error) => console.error(error));
|
.catch((error) => console.error(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function flattenErrors(errors: StructuredErrors): string[] {
|
||||||
|
if(errors instanceof Array) {
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
return Object.keys(errors).map((key) => {
|
||||||
|
return `${key}: ${asArray(errors[key]).join(', ')}`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function register({slug, email, password, passwordConfirmation, captcha, onRegister, onError}: {
|
||||||
|
slug: string,
|
||||||
|
email: string,
|
||||||
|
password: string,
|
||||||
|
passwordConfirmation: string,
|
||||||
|
captcha: Captcha,
|
||||||
|
onRegister: () => void,
|
||||||
|
onError: (errors: string[]) => void
|
||||||
|
}){
|
||||||
|
fetch(`/api/${slug}/users`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(
|
||||||
|
{
|
||||||
|
user: { email, password, password_confirmation: passwordConfirmation },
|
||||||
|
captcha: { id: captcha.id, answer: captcha.answer }
|
||||||
|
}
|
||||||
|
),
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-CSRF-TOKEN': getCsrfToken(),
|
||||||
|
}
|
||||||
|
}).then((response) => {
|
||||||
|
if(response.ok) {
|
||||||
|
response.json().then(onRegister);
|
||||||
|
} else {
|
||||||
|
response.json().then((data: any) => {
|
||||||
|
onError(data.errors && flattenErrors(data.errors) || [data.error]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
19
app/api/captcha.tsx
Normal file
19
app/api/captcha.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/* Copyright (C) 2024 Manuel Bustillo*/
|
||||||
|
|
||||||
|
import { data } from "autoprefixer";
|
||||||
|
import { getCsrfToken } from "../lib/utils";
|
||||||
|
|
||||||
|
export function getCaptchaChallenge({onRetrieve}: {onRetrieve: (id: string, url: string) => void}){
|
||||||
|
return fetch('/api/captcha', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'X-CSRF-TOKEN': getCsrfToken(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((data: any) => {
|
||||||
|
onRetrieve(data.id, data.media_url)
|
||||||
|
})
|
||||||
|
.catch((error) => console.error(error));
|
||||||
|
}
|
@ -65,3 +65,12 @@ export type User = {
|
|||||||
id: string;
|
id: string;
|
||||||
email: string;
|
email: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type Captcha = {
|
||||||
|
id: string;
|
||||||
|
answer: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type StructuredErrors = {
|
||||||
|
[key: string]: string[]|string;
|
||||||
|
};
|
@ -13,3 +13,8 @@ export const getSlug = () => localStorage.getItem('slug') || 'default';
|
|||||||
export const capitalize = (val:string) => {
|
export const capitalize = (val:string) => {
|
||||||
return String(val).charAt(0).toUpperCase() + String(val).slice(1);
|
return String(val).charAt(0).toUpperCase() + String(val).slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// From https://stackoverflow.com/a/62118163/3607039
|
||||||
|
export function asArray<T>(value: T | T[]): T[] {
|
||||||
|
return ([] as T[]).concat(value)
|
||||||
|
}
|
98
app/ui/components/registration-form.tsx
Normal file
98
app/ui/components/registration-form.tsx
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/* Copyright (C) 2024 Manuel Bustillo*/
|
||||||
|
|
||||||
|
'use client';
|
||||||
|
|
||||||
|
import { FloatLabel } from 'primereact/floatlabel';
|
||||||
|
import { InputText } from 'primereact/inputtext';
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { classNames } from './button';
|
||||||
|
import { getSlug } from '@/app/lib/utils';
|
||||||
|
import { register } from '@/app/api/authentication';
|
||||||
|
import { getCaptchaChallenge } from '@/app/api/captcha';
|
||||||
|
|
||||||
|
export default function RegistrationForm() {
|
||||||
|
const [submitted, setSubmitted] = useState<boolean>(false);
|
||||||
|
const [errors, setErrors] = useState<string[]>([]);
|
||||||
|
|
||||||
|
const [email, setEmail] = useState<string>("");
|
||||||
|
const [password, setPassword] = useState<string>("");
|
||||||
|
const [passwordConfirmation, setPasswordConfirmation] = useState<string>("");
|
||||||
|
const [slug, setSlug] = useState<string>(getSlug());
|
||||||
|
|
||||||
|
const [captchaId, setCaptchaId] = useState<string>("");
|
||||||
|
const [captchaUrl, setCaptchaUrl] = useState<string>("");
|
||||||
|
const [captchaAnswer, setCaptchaAnswer] = useState<string>("");
|
||||||
|
|
||||||
|
const refreshCaptcha = () => {
|
||||||
|
getCaptchaChallenge({
|
||||||
|
onRetrieve: (id, url) => {
|
||||||
|
console.log(id, url);
|
||||||
|
setCaptchaId(id);
|
||||||
|
setCaptchaUrl(url);
|
||||||
|
setCaptchaAnswer("");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(refreshCaptcha, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
submitted ? (
|
||||||
|
<div className="card flex justify-evenly py-5 flex-col">
|
||||||
|
<div className="text-green-500">Registration successful. Check your email for a confirmation link.</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
|
||||||
|
<div className="card flex justify-evenly py-5 flex-col">
|
||||||
|
<FloatLabel className="my-4">
|
||||||
|
<InputText id="email" type="email" className='rounded-sm' onChange={(e) => setEmail(e.target.value)} />
|
||||||
|
<label htmlFor="email">Email</label>
|
||||||
|
</FloatLabel>
|
||||||
|
<FloatLabel className="my-4">
|
||||||
|
<InputText id="password" type="password" className='rounded-sm' onChange={(e) => setPassword(e.target.value)} />
|
||||||
|
<label htmlFor="password">Password</label>
|
||||||
|
</FloatLabel>
|
||||||
|
<FloatLabel className="my-4">
|
||||||
|
<InputText id="passwordConfirmation" type="password" className='rounded-sm' onChange={(e) => setPasswordConfirmation(e.target.value)} />
|
||||||
|
<label htmlFor="passwordConfirmation">Confirm Password</label>
|
||||||
|
</FloatLabel>
|
||||||
|
<FloatLabel className="my-4">
|
||||||
|
<InputText id="slug" type="text" className='rounded-sm' onChange={(e) => setSlug(e.target.value)} />
|
||||||
|
<label htmlFor="slug">Slug</label>
|
||||||
|
</FloatLabel>
|
||||||
|
<img className="w-96" src={captchaUrl} alt="captcha" />
|
||||||
|
<FloatLabel className="my-4">
|
||||||
|
<InputText id="captcha" type="text" className='rounded-sm' value={captchaAnswer} onChange={(e) => setCaptchaAnswer(e.target.value)} />
|
||||||
|
<label htmlFor="captcha">Captcha</label>
|
||||||
|
</FloatLabel>
|
||||||
|
|
||||||
|
{errors.map((error, index) => (
|
||||||
|
<div key={index} className="text-red-500">{error}</div>
|
||||||
|
))}
|
||||||
|
|
||||||
|
|
||||||
|
<button
|
||||||
|
className={classNames('primary')}
|
||||||
|
disabled={!(email && password && passwordConfirmation && slug && captchaAnswer)}
|
||||||
|
onClick={() => register(
|
||||||
|
{
|
||||||
|
slug: slug,
|
||||||
|
email: email,
|
||||||
|
password: password,
|
||||||
|
passwordConfirmation: passwordConfirmation,
|
||||||
|
captcha: {
|
||||||
|
id: captchaId,
|
||||||
|
answer: captchaAnswer
|
||||||
|
},
|
||||||
|
onRegister: () => { setErrors([]); setSubmitted(true) },
|
||||||
|
onError: (errors) => { refreshCaptcha(); setErrors(errors) }
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
Register
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
@ -11,7 +11,7 @@
|
|||||||
"autoprefixer": "10.4.20",
|
"autoprefixer": "10.4.20",
|
||||||
"bcrypt": "^5.1.1",
|
"bcrypt": "^5.1.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"next": "15.0.3",
|
"next": "15.0.4",
|
||||||
"next-auth": "5.0.0-beta.25",
|
"next-auth": "5.0.0-beta.25",
|
||||||
"postcss": "8.4.49",
|
"postcss": "8.4.49",
|
||||||
"primeicons": "^7.0.0",
|
"primeicons": "^7.0.0",
|
||||||
|
92
pnpm-lock.yaml
generated
92
pnpm-lock.yaml
generated
@ -24,11 +24,11 @@ importers:
|
|||||||
specifier: ^2.1.1
|
specifier: ^2.1.1
|
||||||
version: 2.1.1
|
version: 2.1.1
|
||||||
next:
|
next:
|
||||||
specifier: 15.0.3
|
specifier: 15.0.4
|
||||||
version: 15.0.3(@playwright/test@1.49.0)(react-dom@19.0.0-rc-f38c22b244-20240704(react@19.0.0-rc-f38c22b244-20240704))(react@19.0.0-rc-f38c22b244-20240704)
|
version: 15.0.4(@playwright/test@1.49.0)(react-dom@19.0.0-rc-f38c22b244-20240704(react@19.0.0-rc-f38c22b244-20240704))(react@19.0.0-rc-f38c22b244-20240704)
|
||||||
next-auth:
|
next-auth:
|
||||||
specifier: 5.0.0-beta.25
|
specifier: 5.0.0-beta.25
|
||||||
version: 5.0.0-beta.25(next@15.0.3(@playwright/test@1.49.0)(react-dom@19.0.0-rc-f38c22b244-20240704(react@19.0.0-rc-f38c22b244-20240704))(react@19.0.0-rc-f38c22b244-20240704))(react@19.0.0-rc-f38c22b244-20240704)
|
version: 5.0.0-beta.25(next@15.0.4(@playwright/test@1.49.0)(react-dom@19.0.0-rc-f38c22b244-20240704(react@19.0.0-rc-f38c22b244-20240704))(react@19.0.0-rc-f38c22b244-20240704))(react@19.0.0-rc-f38c22b244-20240704)
|
||||||
postcss:
|
postcss:
|
||||||
specifier: 8.4.49
|
specifier: 8.4.49
|
||||||
version: 8.4.49
|
version: 8.4.49
|
||||||
@ -236,53 +236,53 @@ packages:
|
|||||||
resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==}
|
resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
'@next/env@15.0.3':
|
'@next/env@15.0.4':
|
||||||
resolution: {integrity: sha512-t9Xy32pjNOvVn2AS+Utt6VmyrshbpfUMhIjFO60gI58deSo/KgLOp31XZ4O+kY/Is8WAGYwA5gR7kOb1eORDBA==}
|
resolution: {integrity: sha512-WNRvtgnRVDD4oM8gbUcRc27IAhaL4eXQ/2ovGbgLnPGUvdyDr8UdXP4Q/IBDdAdojnD2eScryIDirv0YUCjUVw==}
|
||||||
|
|
||||||
'@next/swc-darwin-arm64@15.0.3':
|
'@next/swc-darwin-arm64@15.0.4':
|
||||||
resolution: {integrity: sha512-s3Q/NOorCsLYdCKvQlWU+a+GeAd3C8Rb3L1YnetsgwXzhc3UTWrtQpB/3eCjFOdGUj5QmXfRak12uocd1ZiiQw==}
|
resolution: {integrity: sha512-QecQXPD0yRHxSXWL5Ff80nD+A56sUXZG9koUsjWJwA2Z0ZgVQfuy7gd0/otjxoOovPVHR2eVEvPMHbtZP+pf9w==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
|
|
||||||
'@next/swc-darwin-x64@15.0.3':
|
'@next/swc-darwin-x64@15.0.4':
|
||||||
resolution: {integrity: sha512-Zxl/TwyXVZPCFSf0u2BNj5sE0F2uR6iSKxWpq4Wlk/Sv9Ob6YCKByQTkV2y6BCic+fkabp9190hyrDdPA/dNrw==}
|
resolution: {integrity: sha512-pb7Bye3y1Og3PlCtnz2oO4z+/b3pH2/HSYkLbL0hbVuTGil7fPen8/3pyyLjdiTLcFJ+ymeU3bck5hd4IPFFCA==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
|
|
||||||
'@next/swc-linux-arm64-gnu@15.0.3':
|
'@next/swc-linux-arm64-gnu@15.0.4':
|
||||||
resolution: {integrity: sha512-T5+gg2EwpsY3OoaLxUIofmMb7ohAUlcNZW0fPQ6YAutaWJaxt1Z1h+8zdl4FRIOr5ABAAhXtBcpkZNwUcKI2fw==}
|
resolution: {integrity: sha512-12oSaBFjGpB227VHzoXF3gJoK2SlVGmFJMaBJSu5rbpaoT5OjP5OuCLuR9/jnyBF1BAWMs/boa6mLMoJPRriMA==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@next/swc-linux-arm64-musl@15.0.3':
|
'@next/swc-linux-arm64-musl@15.0.4':
|
||||||
resolution: {integrity: sha512-WkAk6R60mwDjH4lG/JBpb2xHl2/0Vj0ZRu1TIzWuOYfQ9tt9NFsIinI1Epma77JVgy81F32X/AeD+B2cBu/YQA==}
|
resolution: {integrity: sha512-QARO88fR/a+wg+OFC3dGytJVVviiYFEyjc/Zzkjn/HevUuJ7qGUUAUYy5PGVWY1YgTzeRYz78akQrVQ8r+sMjw==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@next/swc-linux-x64-gnu@15.0.3':
|
'@next/swc-linux-x64-gnu@15.0.4':
|
||||||
resolution: {integrity: sha512-gWL/Cta1aPVqIGgDb6nxkqy06DkwJ9gAnKORdHWX1QBbSZZB+biFYPFti8aKIQL7otCE1pjyPaXpFzGeG2OS2w==}
|
resolution: {integrity: sha512-Z50b0gvYiUU1vLzfAMiChV8Y+6u/T2mdfpXPHraqpypP7yIT2UV9YBBhcwYkxujmCvGEcRTVWOj3EP7XW/wUnw==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@next/swc-linux-x64-musl@15.0.3':
|
'@next/swc-linux-x64-musl@15.0.4':
|
||||||
resolution: {integrity: sha512-QQEMwFd8r7C0GxQS62Zcdy6GKx999I/rTO2ubdXEe+MlZk9ZiinsrjwoiBL5/57tfyjikgh6GOU2WRQVUej3UA==}
|
resolution: {integrity: sha512-7H9C4FAsrTAbA/ENzvFWsVytqRYhaJYKa2B3fyQcv96TkOGVMcvyS6s+sj4jZlacxxTcn7ygaMXUPkEk7b78zw==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@next/swc-win32-arm64-msvc@15.0.3':
|
'@next/swc-win32-arm64-msvc@15.0.4':
|
||||||
resolution: {integrity: sha512-9TEp47AAd/ms9fPNgtgnT7F3M1Hf7koIYYWCMQ9neOwjbVWJsHZxrFbI3iEDJ8rf1TDGpmHbKxXf2IFpAvheIQ==}
|
resolution: {integrity: sha512-Z/v3WV5xRaeWlgJzN9r4PydWD8sXV35ywc28W63i37G2jnUgScA4OOgS8hQdiXLxE3gqfSuHTicUhr7931OXPQ==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
'@next/swc-win32-x64-msvc@15.0.3':
|
'@next/swc-win32-x64-msvc@15.0.4':
|
||||||
resolution: {integrity: sha512-VNAz+HN4OGgvZs6MOoVfnn41kBzT+M+tB+OK4cww6DNyWS6wKaDpaAm/qLeOUbnMh0oVx1+mg0uoYARF69dJyA==}
|
resolution: {integrity: sha512-NGLchGruagh8lQpDr98bHLyWJXOBSmkEAfK980OiNBa7vNm6PsNoPvzTfstT78WyOeMRQphEQ455rggd7Eo+Dw==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
@ -735,16 +735,16 @@ packages:
|
|||||||
nodemailer:
|
nodemailer:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
next@15.0.3:
|
next@15.0.4:
|
||||||
resolution: {integrity: sha512-ontCbCRKJUIoivAdGB34yCaOcPgYXr9AAkV/IwqFfWWTXEPUgLYkSkqBhIk9KK7gGmgjc64B+RdoeIDM13Irnw==}
|
resolution: {integrity: sha512-nuy8FH6M1FG0lktGotamQDCXhh5hZ19Vo0ht1AOIQWrYJLP598TIUagKtvJrfJ5AGwB/WmDqkKaKhMpVifvGPA==}
|
||||||
engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
|
engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@opentelemetry/api': ^1.1.0
|
'@opentelemetry/api': ^1.1.0
|
||||||
'@playwright/test': ^1.41.2
|
'@playwright/test': ^1.41.2
|
||||||
babel-plugin-react-compiler: '*'
|
babel-plugin-react-compiler: '*'
|
||||||
react: ^18.2.0 || 19.0.0-rc-66855b96-20241106
|
react: ^18.2.0 || 19.0.0-rc-66855b96-20241106 || ^19.0.0
|
||||||
react-dom: ^18.2.0 || 19.0.0-rc-66855b96-20241106
|
react-dom: ^18.2.0 || 19.0.0-rc-66855b96-20241106 || ^19.0.0
|
||||||
sass: ^1.3.0
|
sass: ^1.3.0
|
||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
'@opentelemetry/api':
|
'@opentelemetry/api':
|
||||||
@ -1294,30 +1294,30 @@ snapshots:
|
|||||||
- encoding
|
- encoding
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@next/env@15.0.3': {}
|
'@next/env@15.0.4': {}
|
||||||
|
|
||||||
'@next/swc-darwin-arm64@15.0.3':
|
'@next/swc-darwin-arm64@15.0.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@next/swc-darwin-x64@15.0.3':
|
'@next/swc-darwin-x64@15.0.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@next/swc-linux-arm64-gnu@15.0.3':
|
'@next/swc-linux-arm64-gnu@15.0.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@next/swc-linux-arm64-musl@15.0.3':
|
'@next/swc-linux-arm64-musl@15.0.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@next/swc-linux-x64-gnu@15.0.3':
|
'@next/swc-linux-x64-gnu@15.0.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@next/swc-linux-x64-musl@15.0.3':
|
'@next/swc-linux-x64-musl@15.0.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@next/swc-win32-arm64-msvc@15.0.3':
|
'@next/swc-win32-arm64-msvc@15.0.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@next/swc-win32-x64-msvc@15.0.3':
|
'@next/swc-win32-x64-msvc@15.0.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@nodelib/fs.scandir@2.1.5':
|
'@nodelib/fs.scandir@2.1.5':
|
||||||
@ -1729,15 +1729,15 @@ snapshots:
|
|||||||
|
|
||||||
nanoid@3.3.7: {}
|
nanoid@3.3.7: {}
|
||||||
|
|
||||||
next-auth@5.0.0-beta.25(next@15.0.3(@playwright/test@1.49.0)(react-dom@19.0.0-rc-f38c22b244-20240704(react@19.0.0-rc-f38c22b244-20240704))(react@19.0.0-rc-f38c22b244-20240704))(react@19.0.0-rc-f38c22b244-20240704):
|
next-auth@5.0.0-beta.25(next@15.0.4(@playwright/test@1.49.0)(react-dom@19.0.0-rc-f38c22b244-20240704(react@19.0.0-rc-f38c22b244-20240704))(react@19.0.0-rc-f38c22b244-20240704))(react@19.0.0-rc-f38c22b244-20240704):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@auth/core': 0.37.2
|
'@auth/core': 0.37.2
|
||||||
next: 15.0.3(@playwright/test@1.49.0)(react-dom@19.0.0-rc-f38c22b244-20240704(react@19.0.0-rc-f38c22b244-20240704))(react@19.0.0-rc-f38c22b244-20240704)
|
next: 15.0.4(@playwright/test@1.49.0)(react-dom@19.0.0-rc-f38c22b244-20240704(react@19.0.0-rc-f38c22b244-20240704))(react@19.0.0-rc-f38c22b244-20240704)
|
||||||
react: 19.0.0-rc-f38c22b244-20240704
|
react: 19.0.0-rc-f38c22b244-20240704
|
||||||
|
|
||||||
next@15.0.3(@playwright/test@1.49.0)(react-dom@19.0.0-rc-f38c22b244-20240704(react@19.0.0-rc-f38c22b244-20240704))(react@19.0.0-rc-f38c22b244-20240704):
|
next@15.0.4(@playwright/test@1.49.0)(react-dom@19.0.0-rc-f38c22b244-20240704(react@19.0.0-rc-f38c22b244-20240704))(react@19.0.0-rc-f38c22b244-20240704):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@next/env': 15.0.3
|
'@next/env': 15.0.4
|
||||||
'@swc/counter': 0.1.3
|
'@swc/counter': 0.1.3
|
||||||
'@swc/helpers': 0.5.13
|
'@swc/helpers': 0.5.13
|
||||||
busboy: 1.6.0
|
busboy: 1.6.0
|
||||||
@ -1747,14 +1747,14 @@ snapshots:
|
|||||||
react-dom: 19.0.0-rc-f38c22b244-20240704(react@19.0.0-rc-f38c22b244-20240704)
|
react-dom: 19.0.0-rc-f38c22b244-20240704(react@19.0.0-rc-f38c22b244-20240704)
|
||||||
styled-jsx: 5.1.6(react@19.0.0-rc-f38c22b244-20240704)
|
styled-jsx: 5.1.6(react@19.0.0-rc-f38c22b244-20240704)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@next/swc-darwin-arm64': 15.0.3
|
'@next/swc-darwin-arm64': 15.0.4
|
||||||
'@next/swc-darwin-x64': 15.0.3
|
'@next/swc-darwin-x64': 15.0.4
|
||||||
'@next/swc-linux-arm64-gnu': 15.0.3
|
'@next/swc-linux-arm64-gnu': 15.0.4
|
||||||
'@next/swc-linux-arm64-musl': 15.0.3
|
'@next/swc-linux-arm64-musl': 15.0.4
|
||||||
'@next/swc-linux-x64-gnu': 15.0.3
|
'@next/swc-linux-x64-gnu': 15.0.4
|
||||||
'@next/swc-linux-x64-musl': 15.0.3
|
'@next/swc-linux-x64-musl': 15.0.4
|
||||||
'@next/swc-win32-arm64-msvc': 15.0.3
|
'@next/swc-win32-arm64-msvc': 15.0.4
|
||||||
'@next/swc-win32-x64-msvc': 15.0.3
|
'@next/swc-win32-x64-msvc': 15.0.4
|
||||||
'@playwright/test': 1.49.0
|
'@playwright/test': 1.49.0
|
||||||
sharp: 0.33.5
|
sharp: 0.33.5
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user