Merge branch 'develop' into develop

This commit is contained in:
David Mehren 2021-01-10 18:04:32 +01:00 committed by GitHub
commit e15fb2c8a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 158 additions and 38 deletions

View file

@ -1,6 +1,6 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value="SPDX-FileCopyrightText: 2020 The HedgeDoc developers (see AUTHORS file)&#10;&#10;&#83;PDX-License-Identifier: AGPL-3.0-only" />
<option name="notice" value="SPDX-FileCopyrightText: $today.year The HedgeDoc developers (see AUTHORS file)&#10;&#10;&#83;PDX-License-Identifier: AGPL-3.0-only" />
<option name="myName" value="hedgedoc" />
</copyright>
</component>

View file

@ -1,5 +1,4 @@
History of CodiMD
===
# History of HedgeDoc
## It started with HackMD
@ -27,14 +26,29 @@ project), as people mistook it for an open core development model.
## CodiMD went independent
In March 2019, a discussion over licensing, governance and the future of CodiMD
lead to the formation of a distinct GitHub organization. Up to that point, the
community project resided in the organization of hackmdio but was for the most
part self-organized.
In March 2019, a discussion over licensing, governance and the future of CodiMD lead to the formation of a distinct
GitHub organization. Up to that point, the community project resided in the organization of hackmdio but was for the
most part self-organized.
During that debate, we did not reach an agreement that would have allowed us to
move the repository, so we simply forked it. We still welcome the HackMD team
as part of our community, especially since a large portion of this code base
During that debate, we did not reach an agreement that would have allowed us to move the repository, so we simply forked
it. We still welcome the HackMD team as part of our community, especially since a large portion of this code base
originated with them.
*For the debate that lead to this step, please refer to the [governance debate](https://github.com/hackmdio/hackmd/issues/1170) and [the announcement of the new repository](https://github.com/codimd/server/issues/10).*
*For the debate that lead to this step, please refer to
the [governance debate](https://github.com/hackmdio/hackmd/issues/1170)
and [the announcement of the new repository](https://github.com/hedgedoc/hedgedoc/issues/10).*
## CodiMD became HedgeDoc
With two actively named forks sharing the same name,
both [insisting on being the original/actual owner of the name CodiMD](https://github.com/hackmdio/codimd/issues/1219),
people became rightfully confused about the projects sharing the same name.
After roughly a year of being stuck on the name issue, the HedgeDoc community decided to take action and started
a [renaming process in April 2020](https://community.codimd.org/t/renaming-yet-another-time/102). With a good head start
in the amount of names, it was decided that an entire rebranding should take place and therefore, after
a [name was agreed on in July 2020](https://community.codimd.org/t/codimd-becomes-hedgedoc/170), the next step was
to [find a logo](https://community.codimd.org/t/time-to-find-the-hedgedoc-logo/171).
In November of 2020, roughly 7 months after the initiative was started, a logo was found, the rebranding of the
application as well as all community pages took place and the time of name conflicts was over. (hopefully.)

View file

@ -39,7 +39,7 @@
"rimraf": "3.0.2",
"rxjs": "6.6.3",
"shortid": "2.2.16",
"sqlite3": "5.0.0",
"sqlite3": "5.0.1",
"swagger-ui-express": "4.1.6",
"typeorm": "0.2.29"
},

View file

@ -10,12 +10,13 @@ import {
Delete,
Get,
Header,
NotFoundException,
Param,
Post,
Put,
} from '@nestjs/common';
import { NotInDBError } from '../../../errors/errors';
import { ConsoleLoggerService } from '../../../logger/console-logger.service';
import { NoteMetadataUpdateDto } from '../../../notes/note-metadata.dto';
import { NotePermissionsUpdateDto } from '../../../notes/note-permissions.dto';
import { NotesService } from '../../../notes/notes.service';
import { RevisionsService } from '../../../revisions/revisions.service';
@ -38,8 +39,15 @@ export class NotesController {
}
@Get(':noteIdOrAlias')
getNote(@Param('noteIdOrAlias') noteIdOrAlias: string) {
return this.noteService.getNoteDtoByIdOrAlias(noteIdOrAlias);
async getNote(@Param('noteIdOrAlias') noteIdOrAlias: string) {
try {
return await this.noteService.getNoteDtoByIdOrAlias(noteIdOrAlias);
} catch (e) {
if (e instanceof NotInDBError) {
throw new NotFoundException(e.message);
}
throw e;
}
}
@Post(':noteAlias')
@ -54,7 +62,14 @@ export class NotesController {
@Delete(':noteIdOrAlias')
async deleteNote(@Param('noteIdOrAlias') noteIdOrAlias: string) {
this.logger.debug('Deleting note: ' + noteIdOrAlias);
try {
await this.noteService.deleteNoteByIdOrAlias(noteIdOrAlias);
} catch (e) {
if (e instanceof NotInDBError) {
throw new NotFoundException(e.message);
}
throw e;
}
this.logger.debug('Successfully deleted ' + noteIdOrAlias);
return;
}
@ -65,38 +80,88 @@ export class NotesController {
@MarkdownBody() text: string,
) {
this.logger.debug('Got raw markdown:\n' + text);
return this.noteService.updateNoteByIdOrAlias(noteIdOrAlias, text);
try {
return await this.noteService.updateNoteByIdOrAlias(noteIdOrAlias, text);
} catch (e) {
if (e instanceof NotInDBError) {
throw new NotFoundException(e.message);
}
throw e;
}
}
@Get(':noteIdOrAlias/content')
@Header('content-type', 'text/markdown')
getNoteContent(@Param('noteIdOrAlias') noteIdOrAlias: string) {
return this.noteService.getNoteContent(noteIdOrAlias);
async getNoteContent(@Param('noteIdOrAlias') noteIdOrAlias: string) {
try {
return await this.noteService.getNoteContent(noteIdOrAlias);
} catch (e) {
if (e instanceof NotInDBError) {
throw new NotFoundException(e.message);
}
throw e;
}
}
@Get(':noteIdOrAlias/metadata')
getNoteMetadata(@Param('noteIdOrAlias') noteIdOrAlias: string) {
return this.noteService.getNoteMetadata(noteIdOrAlias);
async getNoteMetadata(@Param('noteIdOrAlias') noteIdOrAlias: string) {
try {
return await this.noteService.getNoteMetadata(noteIdOrAlias);
} catch (e) {
if (e instanceof NotInDBError) {
throw new NotFoundException(e.message);
}
throw e;
}
}
@Put(':noteIdOrAlias/permissions')
updateNotePermissions(
async updateNotePermissions(
@Param('noteIdOrAlias') noteIdOrAlias: string,
@Body() updateDto: NotePermissionsUpdateDto,
) {
return this.noteService.updateNotePermissions(noteIdOrAlias, updateDto);
try {
return await this.noteService.updateNotePermissions(
noteIdOrAlias,
updateDto,
);
} catch (e) {
if (e instanceof NotInDBError) {
throw new NotFoundException(e.message);
}
throw e;
}
}
@Get(':noteIdOrAlias/revisions')
getNoteRevisions(@Param('noteIdOrAlias') noteIdOrAlias: string) {
return this.revisionsService.getNoteRevisionMetadatas(noteIdOrAlias);
async getNoteRevisions(@Param('noteIdOrAlias') noteIdOrAlias: string) {
try {
return await this.revisionsService.getNoteRevisionMetadatas(
noteIdOrAlias,
);
} catch (e) {
if (e instanceof NotInDBError) {
throw new NotFoundException(e.message);
}
throw e;
}
}
@Get(':noteIdOrAlias/revisions/:revisionId')
getNoteRevision(
async getNoteRevision(
@Param('noteIdOrAlias') noteIdOrAlias: string,
@Param('revisionId') revisionId: number,
) {
return this.revisionsService.getNoteRevision(noteIdOrAlias, revisionId);
try {
return await this.revisionsService.getNoteRevision(
noteIdOrAlias,
revisionId,
);
} catch (e) {
if (e instanceof NotInDBError) {
throw new NotFoundException(e.message);
}
throw e;
}
}
}

View file

@ -59,12 +59,19 @@ describe('Notes', () => {
});
it(`GET /notes/{note}`, async () => {
// check if we can succefully get a note that exists
await notesService.createNote('This is a test note.', 'test1');
const response = await request(app.getHttpServer())
.get('/notes/test1')
.expect('Content-Type', /json/)
.expect(200);
expect(response.body.content).toEqual('This is a test note.');
// check if a missing note correctly returns 404
await request(app.getHttpServer())
.get('/notes/i_dont_exist')
.expect('Content-Type', /json/)
.expect(404);
});
it(`POST /notes/{note}`, async () => {
@ -85,9 +92,13 @@ describe('Notes', () => {
it(`DELETE /notes/{note}`, async () => {
await notesService.createNote('This is a test note.', 'test3');
await request(app.getHttpServer()).delete('/notes/test3').expect(200);
return expect(notesService.getNoteByIdOrAlias('test3')).rejects.toEqual(
await expect(notesService.getNoteByIdOrAlias('test3')).rejects.toEqual(
new NotInDBError("Note with id/alias 'test3' not found."),
);
// check if a missing note correctly returns 404
await request(app.getHttpServer())
.delete('/notes/i_dont_exist')
.expect(404);
});
it(`PUT /notes/{note}`, async () => {
@ -97,9 +108,16 @@ describe('Notes', () => {
.set('Content-Type', 'text/markdown')
.send('New note text')
.expect(200);
return expect(
await expect(
(await notesService.getNoteDtoByIdOrAlias('test4')).content,
).toEqual('New note text');
// check if a missing note correctly returns 404
await request(app.getHttpServer())
.put('/notes/i_dont_exist')
.set('Content-Type', 'text/markdown')
.expect('Content-Type', /json/)
.expect(404);
});
it(`GET /notes/{note}/metadata`, async () => {
@ -124,6 +142,12 @@ describe('Notes', () => {
expect(typeof metadata.body.updateUser.photo).toEqual('string');
expect(typeof metadata.body.viewCount).toEqual('number');
expect(metadata.body.editedBy).toEqual([]);
// check if a missing note correctly returns 404
await request(app.getHttpServer())
.get('/notes/i_dont_exist/metadata')
.expect('Content-Type', /json/)
.expect(404);
});
it(`GET /notes/{note}/revisions`, async () => {
@ -133,6 +157,12 @@ describe('Notes', () => {
.expect('Content-Type', /json/)
.expect(200);
expect(response.body).toHaveLength(1);
// check if a missing note correctly returns 404
await request(app.getHttpServer())
.get('/notes/i_dont_exist/revisions')
.expect('Content-Type', /json/)
.expect(404);
});
it(`GET /notes/{note}/revisions/{revision-id}`, async () => {
@ -143,6 +173,12 @@ describe('Notes', () => {
.expect('Content-Type', /json/)
.expect(200);
expect(response.body.content).toEqual('This is a test note.');
// check if a missing note correctly returns 404
await request(app.getHttpServer())
.get('/notes/i_dont_exist/revisions/1')
.expect('Content-Type', /json/)
.expect(404);
});
it(`GET /notes/{note}/content`, async () => {
@ -151,6 +187,11 @@ describe('Notes', () => {
.get('/notes/test9/content')
.expect(200);
expect(response.text).toEqual('This is a test note.');
// check if a missing note correctly returns 404
await request(app.getHttpServer())
.get('/notes/i_dont_exist/content')
.expect(404);
});
afterAll(async () => {

View file

@ -4942,10 +4942,10 @@ nice-try@^1.0.4:
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
node-addon-api@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.0.tgz#f9afb8d777a91525244b01775ea0ddbe1125483b"
integrity sha512-ASCL5U13as7HhOExbT6OlWJJUV/lLzL2voOSP1UVehpRD8FbSrSDjfScK/KwAvVTI5AS6r4VwbOMlIqtvRidnA==
node-addon-api@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.1.0.tgz#98b21931557466c6729e51cb77cd39c965f42239"
integrity sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw==
node-emoji@1.10.0:
version "1.10.0"
@ -6287,12 +6287,12 @@ sprintf-js@~1.0.2:
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
sqlite3@5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-5.0.0.tgz#1bfef2151c6bc48a3ab1a6c126088bb8dd233566"
integrity sha512-rjvqHFUaSGnzxDy2AHCwhHy6Zp6MNJzCPGYju4kD8yi6bze4d1/zMTg6C7JI49b7/EM7jKMTvyfN/4ylBKdwfw==
sqlite3@5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-5.0.1.tgz#d5b58c8d1568bbaf13062eb9465982f36324f78a"
integrity sha512-kh2lTIcYNfmVcvhVJihsYuPj9U0xzBbh6bmqILO2hkryWSC9RRhzYmkIDtJkJ+d8Kg4wZRJ0T1reyHUEspICfg==
dependencies:
node-addon-api "2.0.0"
node-addon-api "^3.0.0"
node-pre-gyp "^0.11.0"
optionalDependencies:
node-gyp "3.x"