diff --git a/README.md b/README.md index ad0dcce..00740cd 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,4 @@ # 🚀 Getting started with PomeloNote -### **THIS REPOSITORY HAS DEPENDENCIES WITH SECURITY VULNERABILITIES. YOU MIGHT WANT TO UPDATE PACKAGES BEFORE USE.** -## Setup -- run `npm i` -- get the .env file and save it to the root directory of the project -- set up Strapi - - go to `localhost:1337/admin` - - register an admin user - - go to Settings => Users&Permissions Plugin => Roles => Authenticated => Note => Select all - - Save ### Starting the container with svelte and strapi: ``docker-compose up --build -d`` diff --git a/backend/strapi/src/api/note/controllers/note.js b/backend/strapi/src/api/note/controllers/note.js index 84e7a8d..9cf8879 100644 --- a/backend/strapi/src/api/note/controllers/note.js +++ b/backend/strapi/src/api/note/controllers/note.js @@ -50,9 +50,6 @@ module.exports = createCoreController(noteUid, ({strapi}) => ({ lastViewed: Date.now() } }) - entry = await strapi.entityService.findOne(noteUid, noteId, { - populate: ['owners'], - }); return JSON.stringify(entry); } else { ctx.response.status = 403; @@ -66,26 +63,22 @@ module.exports = createCoreController(noteUid, ({strapi}) => ({ async update(ctx) { const noteId = getNoteIdFromUrl(ctx.request.url) const userId = ctx.state.user.id; - const requestBody = JSON.parse(ctx.request.body); - console.log(JSON.stringify(requestBody, null, 2)) + const requestBody = ctx.request.body; const entry = await strapi.entityService.findOne(noteUid, noteId, { populate: ['owners'], }); const authorized = entry.owners.some(owner => owner.id === userId) - let allPreviousOwnersKept = true; + let allPreviousOwnersKept = false; if (requestBody.data.hasOwnProperty("owners")) { allPreviousOwnersKept = entry.owners.every(owner => requestBody.data.owners.includes(owner)); } - console.log({ - "auth": authorized, - "allprev": allPreviousOwnersKept, - }) if (!authorized) { ctx.response.status = 403; } else if (!allPreviousOwnersKept) { ctx.response.status = 400; + } else { + return super.update(ctx); } - return await strapi.entityService.update(noteUid, noteId, requestBody); }, /** * Creates a new note, automatically sets owners to the user making the request and lastViewed diff --git a/backend/strapi/src/extensions/users-permissions/content-types/user/schema.json b/backend/strapi/src/extensions/users-permissions/content-types/user/schema.json deleted file mode 100644 index 7413352..0000000 --- a/backend/strapi/src/extensions/users-permissions/content-types/user/schema.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "kind": "collectionType", - "collectionName": "up_users", - "info": { - "name": "user", - "description": "", - "singularName": "user", - "pluralName": "users", - "displayName": "User" - }, - "options": { - "draftAndPublish": false, - "timestamps": true - }, - "attributes": { - "username": { - "type": "string", - "minLength": 3, - "unique": true, - "configurable": false, - "required": true - }, - "email": { - "type": "email", - "minLength": 6, - "configurable": false, - "required": true - }, - "provider": { - "type": "string", - "configurable": false - }, - "password": { - "type": "password", - "minLength": 6, - "configurable": false, - "private": true - }, - "resetPasswordToken": { - "type": "string", - "configurable": false, - "private": true - }, - "confirmationToken": { - "type": "string", - "configurable": false, - "private": true - }, - "confirmed": { - "type": "boolean", - "default": false, - "configurable": false - }, - "blocked": { - "type": "boolean", - "default": false, - "configurable": false - }, - "role": { - "type": "relation", - "relation": "manyToOne", - "target": "plugin::users-permissions.role", - "inversedBy": "users", - "configurable": false - }, - "notes": { - "type": "relation", - "relation": "manyToMany", - "target": "api::note.note", - "inversedBy": "owners" - } - } -} diff --git a/docs/_config.yml b/docs/_config.yml deleted file mode 100644 index 2e92aba..0000000 --- a/docs/_config.yml +++ /dev/null @@ -1,3 +0,0 @@ -remote_theme: pages-themes/leap-day@v0.2.0 -plugins: -- jekyll-remote-theme diff --git a/docs/_data/devs.csv b/docs/_data/devs.csv deleted file mode 100644 index 5c60b6c..0000000 --- a/docs/_data/devs.csv +++ /dev/null @@ -1,4 +0,0 @@ -name,github,image -Jonas Weissengruber,j-weissen,jowei -Stefan Prechtler,s-prechtl,stef -David Hain,d-hain,dave \ No newline at end of file diff --git a/docs/images/dave.jpg b/docs/images/dave.jpg deleted file mode 100644 index 9fe6268..0000000 Binary files a/docs/images/dave.jpg and /dev/null differ diff --git a/docs/images/delete.png b/docs/images/delete.png deleted file mode 100644 index 39ae1b5..0000000 Binary files a/docs/images/delete.png and /dev/null differ diff --git a/docs/images/editor.png b/docs/images/editor.png deleted file mode 100644 index 690ef69..0000000 Binary files a/docs/images/editor.png and /dev/null differ diff --git a/docs/images/jowei.jpg b/docs/images/jowei.jpg deleted file mode 100644 index 6785c8d..0000000 Binary files a/docs/images/jowei.jpg and /dev/null differ diff --git a/docs/images/listing.png b/docs/images/listing.png deleted file mode 100644 index 8b1189b..0000000 Binary files a/docs/images/listing.png and /dev/null differ diff --git a/docs/images/login.png b/docs/images/login.png deleted file mode 100644 index e9c1cbd..0000000 Binary files a/docs/images/login.png and /dev/null differ diff --git a/docs/images/register.png b/docs/images/register.png deleted file mode 100644 index 68336c8..0000000 Binary files a/docs/images/register.png and /dev/null differ diff --git a/docs/images/stef.jpg b/docs/images/stef.jpg deleted file mode 100644 index 231d3e3..0000000 Binary files a/docs/images/stef.jpg and /dev/null differ diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index 7c87e05..0000000 --- a/docs/index.md +++ /dev/null @@ -1,31 +0,0 @@ -# Pomelo Note - -This is the best open source note app you will ever find. - -## Login -When first entering the app, you will need to login. If you haven't got an account you may consider [registering](#register), or just not using the app at all. -
- -## Register -A username, an email and a password that's all you need. If you are missing one of those, just don't use the app at all. -
- -## Editor -You can edit your notes with our minimalistic editor interface. -
- -## Listing -Here you can see all your notes. Click on them to open the editor or hover and press the red "X" to delete them. -
- -## Delete -Confirm the deletion. -
- -# The Team -{% for dev in site.data.devs %} - {{ dev.name }} - [GitHub](https://github.com/{{ dev.github }}) - ![{{ dev.name }}](images/{{ dev.image }}.jpg) -{% endfor %} - diff --git a/frontend/svelte/package-lock.json b/frontend/svelte/package-lock.json index d5c5126..63551ad 100644 --- a/frontend/svelte/package-lock.json +++ b/frontend/svelte/package-lock.json @@ -9,9 +9,7 @@ "version": "0.0.1", "dependencies": { "bootstrap-icons": "^1.9.1", - "nookies": "^2.5.2", - "sv-popup": "^0.2.5", - "webworker": "^0.8.4" + "nookies": "^2.5.2" }, "devDependencies": { "@sveltejs/adapter-auto": "next", @@ -2085,11 +2083,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/sv-popup": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/sv-popup/-/sv-popup-0.2.5.tgz", - "integrity": "sha512-JhBu4piXaauamT4vMEcFCydvxJ8e72G7c9F3caZVAPsiFqWPTYT3JDz99FlR+YCnbOp1emsZqqOPVvCwHgURog==" - }, "node_modules/svelte": { "version": "3.50.1", "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.50.1.tgz", @@ -2365,14 +2358,6 @@ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "dev": true }, - "node_modules/webworker": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/webworker/-/webworker-0.8.4.tgz", - "integrity": "sha512-zzsVxtHf+mCn0WuYLarSWfRGmX7JiYKkKvso5FYC7rJ9G8svwGQA5a51Sjq9D2c/rKVU6U/kyBcaI7gUTVlsJg==", - "engines": { - "node": ">=0.4.3" - } - }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", @@ -3839,11 +3824,6 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true }, - "sv-popup": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/sv-popup/-/sv-popup-0.2.5.tgz", - "integrity": "sha512-JhBu4piXaauamT4vMEcFCydvxJ8e72G7c9F3caZVAPsiFqWPTYT3JDz99FlR+YCnbOp1emsZqqOPVvCwHgURog==" - }, "svelte": { "version": "3.50.1", "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.50.1.tgz", @@ -4001,11 +3981,6 @@ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "dev": true }, - "webworker": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/webworker/-/webworker-0.8.4.tgz", - "integrity": "sha512-zzsVxtHf+mCn0WuYLarSWfRGmX7JiYKkKvso5FYC7rJ9G8svwGQA5a51Sjq9D2c/rKVU6U/kyBcaI7gUTVlsJg==" - }, "whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", diff --git a/frontend/svelte/package.json b/frontend/svelte/package.json index 81a0887..7ea33f8 100644 --- a/frontend/svelte/package.json +++ b/frontend/svelte/package.json @@ -22,9 +22,7 @@ }, "type": "module", "dependencies": { - "bootstrap-icons": "^1.9.1", "nookies": "^2.5.2", - "sv-popup": "^0.2.5", - "webworker": "^0.8.4" + "bootstrap-icons": "^1.9.1" } } diff --git a/frontend/svelte/src/app.html b/frontend/svelte/src/app.html index 9d5ca24..07daf74 100644 --- a/frontend/svelte/src/app.html +++ b/frontend/svelte/src/app.html @@ -1,5 +1,5 @@ - + @@ -9,5 +9,11 @@
%sveltekit.body%
+ + - \ No newline at end of file + diff --git a/frontend/svelte/src/customBootstrap.css b/frontend/svelte/src/customBootstrap.css deleted file mode 100644 index 311d8a4..0000000 --- a/frontend/svelte/src/customBootstrap.css +++ /dev/null @@ -1,29 +0,0 @@ - -html, -:root { - --main-txt-color: black; - --cross-txt-color: red; - - --color-primary: #fff494; - --color-primary-600: #fff17a; - --color-primary-700: #ffec47; - --color-primary-800: #ffe714; - --color-primary-900: #e0c900; -} - -.btn-primary { - background-color: var(--color-primary-800) !important; - border: var(--color-primary-800) !important; - color: var(--main-txt-color) !important; -} - -.btn-primary:hover { - background-color: var(--color-primary-900) !important; - border: var(--color-primary-900) !important; - color: var(--main-txt-color) !important; -} - -.btn-primary:disabled { - background-color: var(--color-primary-700) !important; - border: var(--color-primary-700) !important; -} \ No newline at end of file diff --git a/frontend/svelte/src/models/repos/note/NoteRepository.ts b/frontend/svelte/src/models/NoteRepository.ts similarity index 89% rename from frontend/svelte/src/models/repos/note/NoteRepository.ts rename to frontend/svelte/src/models/NoteRepository.ts index 84b6705..c83d5a6 100644 --- a/frontend/svelte/src/models/repos/note/NoteRepository.ts +++ b/frontend/svelte/src/models/NoteRepository.ts @@ -1,4 +1,4 @@ -import type {Note} from "../../types"; +import type {Note} from "./types"; export interface NoteRepository { getNotes(): Promise; diff --git a/frontend/svelte/src/models/PomeloUtils.ts b/frontend/svelte/src/models/PomeloUtils.ts index cfec11b..5d290ae 100644 --- a/frontend/svelte/src/models/PomeloUtils.ts +++ b/frontend/svelte/src/models/PomeloUtils.ts @@ -1,5 +1,4 @@ -import type {Authentication} from "./authentication"; -import {createErrorToast} from "./customToasts"; +import {parseCookies} from "nookies"; /** * Capitalises first letter of string. @@ -23,14 +22,13 @@ export async function bearerFetch(endpoint: string, jwt: string, baseUrl: string }); } -export function handleErrorsFromResponseWithToast(response: Authentication) { - if (response.error != null) { - if (response.error.details.errors) { - for (const error of response.error.details.errors) { - createErrorToast(error.message); - } - } else { - createErrorToast(response.error.message); - } - } -} \ No newline at end of file + +const getJwtCookie = () => { + // @ts-ignore + return parseCookies("/").jwt; +}; + +/** + * JWT Cookie + */ +export const jwt: string = getJwtCookie(); \ No newline at end of file diff --git a/frontend/svelte/src/models/repos/note/StrapiNoteRepository.ts b/frontend/svelte/src/models/StrapiNoteRepository.ts similarity index 82% rename from frontend/svelte/src/models/repos/note/StrapiNoteRepository.ts rename to frontend/svelte/src/models/StrapiNoteRepository.ts index 4043bbf..ab4a68f 100644 --- a/frontend/svelte/src/models/repos/note/StrapiNoteRepository.ts +++ b/frontend/svelte/src/models/StrapiNoteRepository.ts @@ -1,8 +1,6 @@ -import type {Note} from "../../types"; +import type {Note} from "./types"; import {parseCookies} from "nookies"; import type {NoteRepository} from "./NoteRepository"; -import {currentNoteId} from "../../../stores"; - type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' @@ -15,19 +13,13 @@ export class StrapiNoteRepository implements NoteRepository { return this.instance; } - private constructor() { - currentNoteId.subscribe((value) => (this._currentNoteId = value)); - } + private constructor() {} - private _currentNoteId: unknown; + private _currentNoteId: number | undefined; private static apiNoteEndpoint: string = "http://localhost:1337/api/notes" public set currentNoteId(value: number | undefined) { - currentNoteId.set(value || -1); - } - - public get currentNoteId(): number { - return this._currentNoteId; + this._currentNoteId = value; } public async getNotes(): Promise{ @@ -44,7 +36,7 @@ export class StrapiNoteRepository implements NoteRepository { if (this._currentNoteId === null || this._currentNoteId === undefined) { return; } - return await this.getNote(this.currentNoteId); + return await this.getNote(this._currentNoteId); } public async updateNote(id: number, note: Partial): Promise { @@ -78,9 +70,8 @@ export class StrapiNoteRepository implements NoteRepository { return "bearer TOKEN" } - static getAuthorizationHeader() { - // @ts-ignore - const jwt = parseCookies('/').jwt; + private static getAuthorizationHeader() { + const jwt = parseCookies().jwt; return `bearer ${jwt}` } } \ No newline at end of file diff --git a/frontend/svelte/src/models/repos/user/StrapiUserRepo.ts b/frontend/svelte/src/models/repos/user/StrapiUserRepo.ts deleted file mode 100644 index 58f2ea2..0000000 --- a/frontend/svelte/src/models/repos/user/StrapiUserRepo.ts +++ /dev/null @@ -1,93 +0,0 @@ -import type {UserRepository} from "./UserRepository"; -import type {Authentication} from "../../authentication"; -import type {HttpMethod} from "@sveltejs/kit/types/private"; -import {StrapiNoteRepository} from "../note/StrapiNoteRepository"; -import {error} from "@sveltejs/kit"; -import {User} from "../../user"; - -export class StrapiUserRepo implements UserRepository { - private static instance: StrapiUserRepo; - - public static getInstance(verification: boolean = true): StrapiUserRepo { - if (this.instance === undefined || this.instance === null) { - this.instance = new StrapiUserRepo(); - this.instance.verify().then(() => { - if (verification && !this.instance.verified) { - window.location.href = "/login"; - } - }); - } - return this.instance; - } - - private verified: boolean = false; - - private constructor() { - } - - private static api: string = "http://localhost:1337/api" - - private static apiUserEndpoint: string = StrapiUserRepo.api + "/auth/local" - - /** - * Verifies the current users jwt. - * @private - */ - private async verify() { - this.verified = false; - let result = await this.getMe(); - if (!result.error) { - this.verified = true; - } - } - - async getMe(): Promise { - const response = await StrapiUserRepo.fetchStrapi("/me", "GET", null, true, "/users") - return await response.json(); - } - - async registerUser(email: string, username: string, password: string): Promise { - const payload = { - email: email, - password: password, - username: username - }; - const response = await StrapiUserRepo.fetchStrapi("/register", "POST", payload, false); - return await response.json(); - } - - async loginUser(identifier: string, password: string): Promise { - const payload = { - identifier: identifier, - password: password - }; - const response = await StrapiUserRepo.fetchStrapi("/", "POST", payload, false); - return response.json(); - } - - private static async fetchStrapi(path: string, method: HttpMethod, body: any | null = null, authorization: boolean = true, customPath: any = null): Promise { - let requestInit: RequestInit = { - method: method, - }; - if (authorization && body) { - requestInit["headers"] = { - authorization: StrapiNoteRepository.getAuthorizationHeader() ?? '', - 'Accept': 'application/json', - 'Content-Type': 'application/json' - } - } else if (authorization) { - requestInit["headers"] = { - authorization: StrapiNoteRepository.getAuthorizationHeader() ?? '', - } - } else if (body) { - requestInit["headers"] = { - 'Accept': 'application/json', - 'Content-Type': 'application/json' - } - } - if (body) { - requestInit["body"] = JSON.stringify(body) - } - return await fetch((customPath) ? (this.api + customPath + path) : StrapiUserRepo.apiUserEndpoint + path, requestInit); - } -} \ No newline at end of file diff --git a/frontend/svelte/src/models/repos/user/UserRepository.ts b/frontend/svelte/src/models/repos/user/UserRepository.ts deleted file mode 100644 index 3128bfb..0000000 --- a/frontend/svelte/src/models/repos/user/UserRepository.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type {Authentication} from "../../authentication"; - -export interface UserRepository { - /** - * Registers a new user. - * @param email - * @param username - * @param password - */ - registerUser(email: string, username: string, password: string): Promise; - - /** - * Gets the current user. - * @param jwt - */ - getMe(jwt: string): Promise; - - loginUser(identifier: string, password: string): Promise; -} \ No newline at end of file diff --git a/frontend/svelte/src/routes/+page.svelte b/frontend/svelte/src/routes/+page.svelte index e744ac0..016d89f 100644 --- a/frontend/svelte/src/routes/+page.svelte +++ b/frontend/svelte/src/routes/+page.svelte @@ -1,20 +1,17 @@ - + PomeloNote | Home - +
-
@@ -122,34 +119,10 @@
- - - -
-
Do you really want to delete the "{note.title}" note?
-
-
-
- -
-
- -
-
-
- - - -
+
@@ -163,11 +136,17 @@ diff --git a/frontend/svelte/src/routes/login/+page.svelte b/frontend/svelte/src/routes/login/+page.svelte index 537507d..fee4156 100644 --- a/frontend/svelte/src/routes/login/+page.svelte +++ b/frontend/svelte/src/routes/login/+page.svelte @@ -1,9 +1,9 @@