Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…all-2024-eu into dynamic-io
  • Loading branch information
Eprince-hub committed Dec 5, 2024
2 parents ddc760a + 8355ca9 commit 6fcb5c1
Show file tree
Hide file tree
Showing 11 changed files with 590 additions and 591 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ type Props = {
};

export default async function DeleteAnimalNaivePage(props: Props) {
const animal = await deleteAnimalInsecure({
id: Number((await props.params).animalId),
});
const animal = await deleteAnimalInsecure(
Number((await props.params).animalId),
);

if (!animal) {
notFound();
Expand Down
4 changes: 1 addition & 3 deletions app/api/animals/[animalId]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,7 @@ export async function DELETE(
): Promise<NextResponse<AnimalResponseBodyDelete>> {
console.log(Number((await params).animalId));

// const animal = await deleteAnimalInsecure({
// id: Number((await params).animalId),
// });
// const animal = await deleteAnimalInsecure(Number((await params).animalId));

const sessionTokenCookie = (await cookies()).get('sessionToken');

Expand Down
25 changes: 19 additions & 6 deletions app/notes/[noteId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Link from 'next/link';
import { getNote } from '../../../database/notes';
import { getNote, selectNoteExists } from '../../../database/notes';
import { getCookie } from '../../../util/cookies';

type Props = {
Expand All @@ -9,15 +9,28 @@ type Props = {
};
export default async function NotePage({ params }: Props) {
// Task: Restrict access to the note page only to the user who created the note

const noteId = Number((await params).noteId);

// 1. Check if the sessionToken cookie exists
const sessionTokenCookie = await getCookie('sessionToken');

// 2. Query the notes with the session token and noteId
// 2. Check if the note exists
if (!(await selectNoteExists(noteId))) {
return (
<div>
<h1>Error loading note {noteId}</h1>
<div>The note does not exist</div>
<Link href="/notes">Back to notes</Link>
</div>
);
}

// 3. Query the notes with the session token and noteId
const note =
sessionTokenCookie &&
(await getNote(sessionTokenCookie, Number((await params).noteId)));
sessionTokenCookie && (await getNote(sessionTokenCookie, noteId));

// 3. If there is no note for the current user, show restricted access message
// 4. If there is no note for the current user, show restricted access message
if (!note) {
return (
<div>
Expand All @@ -28,7 +41,7 @@ export default async function NotePage({ params }: Props) {
);
}

// 4. Finally display the notes created by the current user
// 5. Finally display the notes created by the current user
return (
<div>
<h1>{note.title}</h1>
Expand Down
37 changes: 25 additions & 12 deletions database/animals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,16 +269,29 @@ export const updateAnimalInsecure = cache(async (updatedAnimal: Animal) => {
return animal;
});

export const deleteAnimalInsecure = cache(
async (deletedAnimal: Pick<Animal, 'id'>) => {
const [animal] = await sql<Animal[]>`
DELETE FROM animals
WHERE
id = ${deletedAnimal.id}
RETURNING
animals.*
`;
export const deleteAnimalInsecure = cache(async (animalId: Animal['id']) => {
const [animal] = await sql<Animal[]>`
DELETE FROM animals
WHERE
id = ${animalId}
RETURNING
animals.*
`;

return animal;
},
);
return animal;
});

// Alternative: Using the TypeScript Pick utility type
// export const deleteAnimalInsecure = cache(
// async (deletedAnimal: Pick<Animal, 'id'>) => {
// const [animal] = await sql<Animal[]>`
// DELETE FROM animals
// WHERE
// id = ${deletedAnimal.id}
// RETURNING
// animals.*
// `;

// return animal;
// },
// );
16 changes: 16 additions & 0 deletions database/notes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,22 @@ export const getNote = cache(async (sessionToken: string, noteId: number) => {
return note;
});

export async function selectNoteExists(noteId: Note['id']) {
const [record] = await sql<{ exists: boolean }[]>`
SELECT
EXISTS (
SELECT
TRUE
FROM
notes
WHERE
id = ${noteId}
)
`;

return Boolean(record?.exists);
}

export const createNote = cache(
async (
sessionToken: Session['token'],
Expand Down
4 changes: 2 additions & 2 deletions fly.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ primary_region = "otp"
[http_service]
internal_port = 8080
force_https = true
auto_stop_machines = true
auto_start_machines = true
auto_stop_machines = "suspend"
auto_start_machines = true
6 changes: 4 additions & 2 deletions jest.config.js → jest.config.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
/** @jest-config-loader esbuild-register */

import type { Config } from 'jest';
import nextJest from 'next/jest.js';

// https://nextjs.org/docs/app/building-your-application/testing/jest
const createJestConfig = nextJest({
dir: './',
});

/** @type {import('jest').Config} */
const config = {
const config: Config = {
testEnvironment: 'jest-environment-jsdom',
testPathIgnorePatterns: ['<rootDir>/playwright/'],
};
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,19 @@
"zod": "^3.23.8"
},
"devDependencies": {
"@jest/globals": "^29.7.0",
"@jest/globals": "^30.0.0-alpha.6",
"@playwright/test": "^1.47.2",
"@ts-safeql/eslint-plugin": "^3.4.7",
"@types/bcrypt": "^5.0.2",
"@types/dotenv-safe": "^8.1.6",
"@types/node": "^22.7.4",
"@types/react": "^18.3.10",
"@types/react-dom": "^18.3.0",
"esbuild-register": "^3.6.0",
"eslint": "^9.11.1",
"eslint-config-upleveled": "^8.8.0",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"jest": "^30.0.0-alpha.6",
"jest-environment-jsdom": "^30.0.0-alpha.6",
"libpg-query": "16.2.0",
"prettier": "^3.3.3",
"prettier-plugin-embed": "^0.4.15",
Expand Down
Loading

0 comments on commit 6fcb5c1

Please sign in to comment.