From bb8297dca33072eb670dc5c512dd8c95dccd9ab5 Mon Sep 17 00:00:00 2001 From: Yannick Bungers Date: Sat, 11 Apr 2020 16:08:40 +0200 Subject: [PATCH] Added Types to actions.js and reformat Signed-off-by: Yannick Bungers Signed-off-by: David Mehren --- lib/models/revision.ts | 4 +- lib/web/note/actions.ts | 144 ++++++++++++++++++------------------- lib/web/note/controller.ts | 105 ++++++++++++++------------- 3 files changed, 122 insertions(+), 131 deletions(-) diff --git a/lib/models/revision.ts b/lib/models/revision.ts index fcac5e7fd..76de7e0ff 100644 --- a/lib/models/revision.ts +++ b/lib/models/revision.ts @@ -114,7 +114,7 @@ export class Revision extends Model { @BelongsTo(() => Note, { foreignKey: 'noteId', constraints: false, onDelete: 'CASCADE', hooks: true }) note: Note; - getNoteRevisions (note: Note, callback): void { + static getNoteRevisions (note: Note, callback): void { Revision.findAll({ where: { noteId: note.id @@ -138,7 +138,7 @@ export class Revision extends Model { }) } - getPatchedNoteRevisionByTime (note: Note, time, errorCallback): void { + static getPatchedNoteRevisionByTime (note: Note, time, errorCallback): void { // find all revisions to prepare for all possible calculation Revision.findAll({ where: { diff --git a/lib/web/note/actions.ts b/lib/web/note/actions.ts index ac52f1fac..30db0f507 100644 --- a/lib/web/note/actions.ts +++ b/lib/web/note/actions.ts @@ -1,87 +1,59 @@ -import {Response} from "express"; +import { Response } from 'express' -const models = require('../../models') -const logger = require('../../logger') -const config = require('../../config') -const errors = require('../../errors') -const shortId = require('shortid') -const moment = require('moment') -const querystring = require('querystring') +import { Note, Revision } from '../../models' +import logger from '../../logger' +import config from '../../config' +import errors from '../../errors' +import shortId from 'shortid' +import moment from 'moment' +import querystring from 'querystring' -export module ActionController { - - // TODO: Use correct type for note - export function getInfo(req: any, res: Response, note: any) { - const body = note.content - const extracted = models.Note.extractMeta(body) - const markdown = extracted.markdown - const meta = models.Note.parseMeta(extracted.meta) - const createtime = note.createdAt - const updatetime = note.lastchangeAt - const title = models.Note.decodeTitle(note.title) - const data = { - title: meta.title || title, - description: meta.description || (markdown ? models.Note.generateDescription(markdown) : null), - viewcount: note.viewcount, - createtime: createtime, - updatetime: updatetime - } - res.set({ - 'Access-Control-Allow-Origin': '*', // allow CORS as API - 'Access-Control-Allow-Headers': 'Range', - 'Access-Control-Expose-Headers': 'Cache-Control, Content-Encoding, Content-Range', - 'Cache-Control': 'private', // only cache by client - 'X-Robots-Tag': 'noindex, nofollow' // prevent crawling - }) - res.send(data) +export function getInfo (req: any, res: Response, note: Note): void { + const body = note.content + const extracted = Note.extractMeta(body) + const markdown = extracted.markdown + const meta = Note.parseMeta(extracted.meta) + const title = Note.decodeTitle(note.title) + const data = { + title: meta.title || title, + description: meta.description || (markdown ? Note.generateDescription(markdown) : null), + viewcount: note.viewcount, + createtime: note.createdAt, + updatetime: note.lastchangeAt } + res.set({ + 'Access-Control-Allow-Origin': '*', // allow CORS as API + 'Access-Control-Allow-Headers': 'Range', + 'Access-Control-Expose-Headers': 'Cache-Control, Content-Encoding, Content-Range', + 'Cache-Control': 'private', // only cache by client + 'X-Robots-Tag': 'noindex, nofollow' // prevent crawling + }) + res.send(data) +} - // TODO: Use correct type for note - export function createGist(req: any, res: Response, note: any) { - const data = { - client_id: config.github.clientID, - redirect_uri: config.serverURL + '/auth/github/callback/' + models.Note.encodeNoteId(note.id) + '/gist', - scope: 'gist', - state: shortId.generate() - } - const query = querystring.stringify(data) - res.redirect('https://github.com/login/oauth/authorize?' + query) +export function createGist (req: any, res: Response, note: Note): void { + const data = { + client_id: config.github.clientID, + redirect_uri: config.serverURL + '/auth/github/callback/' + Note.encodeNoteId(note.id) + '/gist', + scope: 'gist', + state: shortId.generate() } + const query = querystring.stringify(data) + res.redirect('https://github.com/login/oauth/authorize?' + query) +} - // TODO: Use correct type for note - export function getRevision(req: any, res: Response, note: any) { - const actionId = req.params.actionId - if (actionId) { - const time = moment(parseInt(actionId)) - if (time.isValid()) { - models.Revision.getPatchedNoteRevisionByTime(note, time, function (err, content) { - if (err) { - logger.error(err) - return errors.errorInternalError(res) - } - if (!content) { - return errors.errorNotFound(res) - } - res.set({ - 'Access-Control-Allow-Origin': '*', // allow CORS as API - 'Access-Control-Allow-Headers': 'Range', - 'Access-Control-Expose-Headers': 'Cache-Control, Content-Encoding, Content-Range', - 'Cache-Control': 'private', // only cache by client - 'X-Robots-Tag': 'noindex, nofollow' // prevent crawling - }) - res.send(content) - }) - } else { - return errors.errorNotFound(res) - } - } else { - models.Revision.getNoteRevisions(note, function (err, data) { +export function getRevision (req: any, res: Response, note: Note): void { + const actionId = req.params.actionId + if (actionId) { + const time = moment(parseInt(actionId)) + if (time.isValid()) { + Revision.getPatchedNoteRevisionByTime(note, time, function (err, content) { if (err) { logger.error(err) - return errors.errorInternalError(res) + errors.errorInternalError(res) } - const out = { - revision: data + if (!content) { + errors.errorNotFound(res) } res.set({ 'Access-Control-Allow-Origin': '*', // allow CORS as API @@ -90,8 +62,28 @@ export module ActionController { 'Cache-Control': 'private', // only cache by client 'X-Robots-Tag': 'noindex, nofollow' // prevent crawling }) - res.send(out) + res.send(content) }) + } else { + errors.errorNotFound(res) } + } else { + Revision.getNoteRevisions(note, function (err, data) { + if (err) { + logger.error(err) + errors.errorInternalError(res) + } + const out = { + revision: data + } + res.set({ + 'Access-Control-Allow-Origin': '*', // allow CORS as API + 'Access-Control-Allow-Headers': 'Range', + 'Access-Control-Expose-Headers': 'Cache-Control, Content-Encoding, Content-Range', + 'Cache-Control': 'private', // only cache by client + 'X-Robots-Tag': 'noindex, nofollow' // prevent crawling + }) + res.send(out) + }) } } diff --git a/lib/web/note/controller.ts b/lib/web/note/controller.ts index b8184d7f5..3c29ce1ba 100644 --- a/lib/web/note/controller.ts +++ b/lib/web/note/controller.ts @@ -1,41 +1,40 @@ -import {NextFunction, Response} from "express"; -import {NoteUtils} from "./util"; -import { ActionController } from "./actions"; -import errors from "../../errors"; -import config from "../../config"; -import logger from "../../logger"; -import { User } from "../../models/user"; -import { Note } from "../../models/note"; +import { NextFunction, Response } from 'express' +import { NoteUtils } from './util' +import * as ActionController from './actions' +import errors from '../../errors' +import config from '../../config' +import logger from '../../logger' +import { User, Note } from '../../models' export module NoteController { - export function publishNoteActions(req: any, res: Response, next: NextFunction) { + export function publishNoteActions (req: any, res: Response, next: NextFunction) { NoteUtils.findNoteOrCreate(req, res, function (note) { - const action = req.params.action; + const action = req.params.action switch (action) { case 'download': - exports.downloadMarkdown(req, res, note); - break; + exports.downloadMarkdown(req, res, note) + break case 'edit': - res.redirect(config.serverURL + '/' + (note.alias ? note.alias : Note.encodeNoteId(note.id)) + '?both'); - break; + res.redirect(config.serverURL + '/' + (note.alias ? note.alias : Note.encodeNoteId(note.id)) + '?both') + break default: - res.redirect(config.serverURL + '/s/' + note.shortid); + res.redirect(config.serverURL + '/s/' + note.shortid) break } }) } - export function showPublishNote(req: any, res: Response, next: NextFunction) { + export function showPublishNote (req: any, res: Response, next: NextFunction) { const include = [{ model: User, as: 'owner' }, { model: User, as: 'lastchangeuser' - }]; + }] NoteUtils.findNoteOrCreate(req, res, function (note) { // force to use short id - const shortid = req.params.shortid; + const shortid = req.params.shortid if ((note.alias && shortid !== note.alias) || (!note.alias && shortid !== note.shortid)) { return res.redirect(config.serverURL + '/s/' + (note.alias || note.shortid)) } @@ -46,34 +45,34 @@ export module NoteController { NoteUtils.getPublishData(req, res, note, (data) => { res.set({ 'Cache-Control': 'private' // only cache by client - }); + }) return res.render('pretty.ejs', data) }) }).catch(function (err) { - logger.error(err); + logger.error(err) return errors.errorInternalError(res) }) }, include) } - export function showNote(req: any, res: Response, next: NextFunction) { + export function showNote (req: any, res: Response, next: NextFunction) { NoteUtils.findNoteOrCreate(req, res, function (note) { // force to use note id - const noteId = req.params.noteId; - const id = Note.encodeNoteId(note.id); + const noteId = req.params.noteId + const id = Note.encodeNoteId(note.id) if ((note.alias && noteId !== note.alias) || (!note.alias && noteId !== id)) { return res.redirect(config.serverURL + '/' + (note.alias || id)) } - const body = note.content; - const extracted = Note.extractMeta(body); - const meta = Note.parseMeta(extracted.meta); - let title = Note.decodeTitle(note.title); - title = Note.generateWebTitle(meta.title || title); - const opengraph = Note.parseOpengraph(meta, title); + const body = note.content + const extracted = Note.extractMeta(body) + const meta = Note.parseMeta(extracted.meta) + let title = Note.decodeTitle(note.title) + title = Note.generateWebTitle(meta.title || title) + const opengraph = Note.parseOpengraph(meta, title) res.set({ 'Cache-Control': 'private', // only cache by client 'X-Robots-Tag': 'noindex, nofollow' // prevent crawling - }); + }) return res.render('codimd.ejs', { title: title, opengraph: opengraph @@ -81,52 +80,52 @@ export module NoteController { }) } - export function createFromPOST(req: any, res: Response, next: NextFunction) { - let body = ''; + export function createFromPOST (req: any, res: Response, next: NextFunction) { + let body = '' if (req.body && req.body.length > config.documentMaxLength) { return errors.errorTooLong(res) } else if (req.body) { body = req.body } - body = body.replace(/[\r]/g, ''); + body = body.replace(/[\r]/g, '') return NoteUtils.newNote(req, res, body) } - export function doAction(req: any, res: Response, next: NextFunction) { - const noteId = req.params.noteId; + export function doAction (req: any, res: Response, next: NextFunction) { + const noteId = req.params.noteId NoteUtils.findNoteOrCreate(req, res, (note) => { - const action = req.params.action; + const action = req.params.action // TODO: Don't switch on action, choose action in Router and use separate functions switch (action) { case 'publish': case 'pretty': // pretty deprecated - res.redirect(config.serverURL + '/s/' + (note.alias || note.shortid)); - break; + res.redirect(config.serverURL + '/s/' + (note.alias || note.shortid)) + break case 'slide': - res.redirect(config.serverURL + '/p/' + (note.alias || note.shortid)); - break; + res.redirect(config.serverURL + '/p/' + (note.alias || note.shortid)) + break case 'download': - exports.downloadMarkdown(req, res, note); - break; + exports.downloadMarkdown(req, res, note) + break case 'info': - ActionController.getInfo(req, res, note); - break; + ActionController.getInfo(req, res, note) + break case 'gist': - ActionController.createGist(req, res, note); - break; + ActionController.createGist(req, res, note) + break case 'revision': - ActionController.getRevision(req, res, note); - break; + ActionController.getRevision(req, res, note) + break default: return res.redirect(config.serverURL + '/' + noteId) } }) } - export function downloadMarkdown(req: Request, res: Response, note: any) { - const body = note.content; - let filename = Note.decodeTitle(note.title); - filename = encodeURIComponent(filename); + export function downloadMarkdown (req: Request, res: Response, note: any) { + const body = note.content + let filename = Note.decodeTitle(note.title) + filename = encodeURIComponent(filename) res.set({ 'Access-Control-Allow-Origin': '*', // allow CORS as API 'Access-Control-Allow-Headers': 'Range', @@ -135,7 +134,7 @@ export module NoteController { 'Cache-Control': 'private', 'Content-disposition': 'attachment; filename=' + filename + '.md', 'X-Robots-Tag': 'noindex, nofollow' // prevent crawling - }); + }) res.send(body) } }