mirror of
https://github.com/slynn1324/tinypin.git
synced 2026-01-23 02:25:08 +00:00
Added file upload capabilties via the add pin dialog or drag-and-drop on the board page
This commit is contained in:
parent
8ee0acda17
commit
0f3fc05594
11 changed files with 690 additions and 54 deletions
166
client/app.js
166
client/app.js
|
|
@ -71,6 +71,8 @@ app.addSetter('load.board', async (data, force) => {
|
|||
});
|
||||
|
||||
app.addSetter('load.user', async (data) => {
|
||||
|
||||
console.log("load.user");
|
||||
store.do("loader.show");
|
||||
|
||||
let res = await fetch("/api/whoami");
|
||||
|
|
@ -96,6 +98,102 @@ app.addSetter("hash.update", (data) => {
|
|||
}
|
||||
});
|
||||
|
||||
app.addSetter("app.uploadDroppedFiles", async (data, evt) => {
|
||||
|
||||
let boardId = store.data.board.id;
|
||||
|
||||
if ( boardId ){
|
||||
let hasFiles = event.dataTransfer.types.find(i => i == "Files") == "Files";
|
||||
if ( hasFiles ){
|
||||
|
||||
if ( evt.dataTransfer.items ){
|
||||
|
||||
let files = [];
|
||||
|
||||
for ( let i = 0; i < evt.dataTransfer.items.length; ++i ){
|
||||
if ( evt.dataTransfer.items[i].kind === "file" ){
|
||||
let file = evt.dataTransfer.items[i].getAsFile();
|
||||
|
||||
if ( file.type != "image/jpeg" && file.type != "image/png" ){
|
||||
|
||||
window.alert("Unsupported file type. JPEG and PNG images are supported.");
|
||||
console.log("Unsupported file type: " + file.type);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// check size
|
||||
if ( file.size >= 26214400 ){
|
||||
window.alert("File size exceeds the 25MB limit.");
|
||||
console.log("File size exceeds the 25MB limit. size=" + file.size);
|
||||
document.getElementById("fileInput").value = "";
|
||||
return;
|
||||
}
|
||||
|
||||
files.push(file);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Number of files=" + files.length);
|
||||
|
||||
for ( let i = 0; i < files.length; ++i ){
|
||||
|
||||
data.dropUploadMessage = `Uploading ${i+1} of ${files.length}`;
|
||||
|
||||
try {
|
||||
let newPin = await multipartUpload(files[i], boardId);
|
||||
if ( data.board && data.board.id == boardId ){
|
||||
data.board.pins.push(newPin);
|
||||
}
|
||||
} catch (e){
|
||||
window.alert("Error uploading images.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
data.dropUploadMessage = null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
function PostException(statusCode, errorMessage){
|
||||
this.statusCode = statusCode;
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
async function multipartUpload(file, boardId, newBoardName, siteUrl, description){
|
||||
console.log("attempting multipart upload");
|
||||
let formData = new FormData();
|
||||
formData.append("file", file);
|
||||
formData.append("boardId", boardId);
|
||||
if ( newBoardName ){
|
||||
formData.append("newBoardName", newBoardName);
|
||||
}
|
||||
if ( siteUrl ){
|
||||
formData.append("siteUrl", siteUrl);
|
||||
}
|
||||
if ( description ){
|
||||
formData.append("description", description);
|
||||
}
|
||||
|
||||
let res = await fetch("./multiup", {
|
||||
method: "POST",
|
||||
body: formData
|
||||
});
|
||||
|
||||
if ( res.status == 200 ){
|
||||
return res.json();
|
||||
} else {
|
||||
console.error("error uploading status=" + res.status + " body=" + await res.text());
|
||||
throw new PostException(res.status);
|
||||
}
|
||||
}
|
||||
|
||||
function dispatchSocketConnect(){
|
||||
window.dispatchEvent(new CustomEvent("socket-connect"));
|
||||
}
|
||||
|
|
@ -121,7 +219,8 @@ let store = new Reef.Store({
|
|||
previewImageUrl: null,
|
||||
siteUrl: "",
|
||||
description: "",
|
||||
saveInProgress: false
|
||||
saveInProgress: false,
|
||||
didYouKnowDragAndDropMessageDisabled: window.localStorage.addPinModal_didYouKnowDragAndDropMessageDisabled == "true" || false
|
||||
},
|
||||
pinZoomModal: {
|
||||
active: false,
|
||||
|
|
@ -167,6 +266,23 @@ const appComponent = new Reef("#app", {
|
|||
<div id="editBoardModal"></div>
|
||||
<div id="aboutModal"></div>
|
||||
<div id="editPinModal"></div>
|
||||
<div id="dragAndDropModal" class="modal">
|
||||
<div class="modal-background"></div>
|
||||
<div class="modal-content">
|
||||
<div class="box">
|
||||
<div class="m-6">drop to add pins</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal ${data.dropUploadMessage ? 'is-active' : ''}">
|
||||
<div class="modal-background"></div>
|
||||
<div class="modal-content has-text-centered">
|
||||
<div class="box">
|
||||
<div class="button is-text is-large is-loading"></div>
|
||||
<div>${data.dropUploadMessage}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
//<div id="loader" class="button is-text ${data.loading ? 'is-loading' : ''}"></div>
|
||||
}
|
||||
|
|
@ -290,4 +406,50 @@ document.addEventListener("visibilitychange", async () => {
|
|||
}
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
window.dragInProgress = false;
|
||||
|
||||
window.ondragover = (evt) => {
|
||||
|
||||
let data = store.data;
|
||||
|
||||
if ( !data.board || data.addPinModal.active || data.editPinModal.active || data.aboutModal.active || data.pinZoomModal.active ){
|
||||
return;
|
||||
}
|
||||
|
||||
evt.preventDefault();
|
||||
|
||||
let hasFiles = event.dataTransfer.types.find(i => i == "Files") == "Files";
|
||||
if ( hasFiles ){
|
||||
window.dragInProgress = true;
|
||||
document.getElementById("dragAndDropModal").classList.add("is-active");
|
||||
}
|
||||
};
|
||||
|
||||
window.ondragleave = (evt) => {
|
||||
if ( evt.x == 0 && evt.y == 0 ){
|
||||
document.getElementById("dragAndDropModal").classList.remove("is-active");
|
||||
window.dragInProgress = false;
|
||||
}
|
||||
}
|
||||
|
||||
window.ondrop = async (evt) => {
|
||||
|
||||
if ( window.dragInProgress ){
|
||||
evt.preventDefault();
|
||||
|
||||
document.getElementById("dragAndDropModal").classList.remove("is-active");
|
||||
|
||||
let hasFiles = event.dataTransfer.types.find(i => i == "Files") == "Files";
|
||||
if ( hasFiles ){
|
||||
store.do("app.uploadDroppedFiles", evt);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -437,4 +437,15 @@ body.socketConnected #socketConnected {
|
|||
.is-touch .navbar.is-light .navbar-brand .navbar-link:hover,
|
||||
.is-touch .navbar.is-light .navbar-brand .navbar-link.is-active {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
|
||||
#dragAndDropModal .modal-background{
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
#dragAndDropModal .box {
|
||||
background: none;
|
||||
border: 3px dashed #000;
|
||||
text-align: center;
|
||||
}
|
||||
|
|
@ -21,9 +21,18 @@ app.addSetter('addPinModal.close', (data) => {
|
|||
data.addPinModal.description = "";
|
||||
data.addPinModal.newBoardName = "";
|
||||
data.addPinModal.saveInProgress = false;
|
||||
data.addPinModal.uploadFile = null;
|
||||
|
||||
|
||||
// weird hack to pick up whether it redraws or not...
|
||||
let fileInput = document.getElementById("fileInput");
|
||||
if ( fileInput ){
|
||||
fileInput.value = "";
|
||||
}
|
||||
});
|
||||
|
||||
app.addSetter('addPinModal.updatePreview', (data) => {
|
||||
|
||||
if ( data.addPinModal.imageUrl.startsWith("http") ){
|
||||
( async() => {
|
||||
let res = await fetch(data.addPinModal.imageUrl, {
|
||||
|
|
@ -38,6 +47,7 @@ app.addSetter('addPinModal.updatePreview', (data) => {
|
|||
} else {
|
||||
data.addPinModal.previewImageUrl = null;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
app.addSetter('addPinModal.save', async (data) => {
|
||||
|
|
@ -48,37 +58,63 @@ app.addSetter('addPinModal.save', async (data) => {
|
|||
|
||||
let boardId = data.addPinModal.boardId;
|
||||
|
||||
let postData = {
|
||||
boardId: boardId,
|
||||
newBoardName: data.addPinModal.newBoardName,
|
||||
imageUrl: data.addPinModal.imageUrl,
|
||||
siteUrl: data.addPinModal.siteUrl,
|
||||
description: data.addPinModal.description
|
||||
};
|
||||
|
||||
let res = await fetch('api/pins', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': "application/json"
|
||||
},
|
||||
body: JSON.stringify(postData)
|
||||
});
|
||||
|
||||
if ( res.status == 200 ){
|
||||
|
||||
let body = await res.json();
|
||||
if ( data.board && data.board.id == boardId ){
|
||||
data.board.pins.push(body);
|
||||
if ( data.addPinModal.uploadFile ){
|
||||
// do file upload
|
||||
|
||||
console.log("attempting multipart file uploading");
|
||||
|
||||
try {
|
||||
let newPin = await multipartUpload(data.addPinModal.uploadFile, boardId, data.addPinModal.newBoardName, data.addPinModal.siteUrl, data.addPinModal.description);
|
||||
if ( data.board && data.board.id == boardId ){
|
||||
data.board.pins.push(newPin);
|
||||
}
|
||||
|
||||
window.localStorage.addPinLastBoardId = boardId;
|
||||
store.do("addPinModal.close");
|
||||
|
||||
if ( boardId == "new" && !window.socketConnected ){
|
||||
store.do("load.boards");
|
||||
}
|
||||
} catch (e){
|
||||
window.alert("Error uploading images.");
|
||||
console.error("Error uploading images: ", e);
|
||||
}
|
||||
|
||||
window.localStorage.addPinLastBoardId = boardId;
|
||||
store.do("addPinModal.close");
|
||||
} else {
|
||||
|
||||
// if we don't have a listening socket, we need to trigger our own update
|
||||
if ( boardId == "new" && !window.socketConnected ){
|
||||
store.do("load.boards");
|
||||
let postData = {
|
||||
boardId: boardId,
|
||||
newBoardName: data.addPinModal.newBoardName,
|
||||
imageUrl: data.addPinModal.imageUrl,
|
||||
siteUrl: data.addPinModal.siteUrl,
|
||||
description: data.addPinModal.description
|
||||
};
|
||||
|
||||
let res = await fetch('api/pins', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': "application/json"
|
||||
},
|
||||
body: JSON.stringify(postData)
|
||||
});
|
||||
|
||||
if ( res.status == 200 ){
|
||||
|
||||
let body = await res.json();
|
||||
if ( data.board && data.board.id == boardId ){
|
||||
data.board.pins.push(body);
|
||||
}
|
||||
|
||||
window.localStorage.addPinLastBoardId = boardId;
|
||||
store.do("addPinModal.close");
|
||||
|
||||
// if we don't have a listening socket, we need to trigger our own update
|
||||
if ( boardId == "new" && !window.socketConnected ){
|
||||
store.do("load.boards");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
store.do("loader.hide");
|
||||
|
||||
|
|
@ -101,6 +137,54 @@ app.addGetter('addPinModal.isValid', (data) => {
|
|||
return true;
|
||||
});
|
||||
|
||||
app.addSetter('addPinModal.fileChosen', (data, target) => {
|
||||
|
||||
let file = target.files[0];
|
||||
|
||||
// check type
|
||||
if ( file.type != "image/jpeg" && file.type != "image/png" ){
|
||||
|
||||
window.alert("Unsupported file type. JPEG and PNG images are supported.");
|
||||
console.log("Unsupported file type: " + file.type);
|
||||
|
||||
document.getElementById("fileInput").value = "";
|
||||
|
||||
}
|
||||
|
||||
// check size
|
||||
if ( file.size >= 26214400 ){
|
||||
window.alert("File size exceeds the 25MB limit.");
|
||||
console.log("File size exceeds the 25MB limit. size=" + file.size);
|
||||
document.getElementById("fileInput").value = "";
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
let imageUrl = window.URL.createObjectURL(file);
|
||||
|
||||
data.addPinModal.uploadFile = file;
|
||||
data.addPinModal.previewImageUrl = imageUrl;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
app.addSetter('addPinModal.removeUploadFile', (data, target) => {
|
||||
data.addPinModal.uploadFile = null;
|
||||
data.addPinModal.previewImageUrl = null;
|
||||
return false;
|
||||
});
|
||||
|
||||
app.addSetter('addPinModal.disableDidYouKnowDragAndDropMessage', (data) => {
|
||||
data.addPinModal.didYouKnowDragAndDropMessageDisabled = true;
|
||||
window.localStorage.addPinModal_didYouKnowDragAndDropMessageDisabled = "true";
|
||||
});
|
||||
|
||||
document.addEventListener("input", (evt) => {
|
||||
if ( evt.target.id == "fileInput" ){
|
||||
store.do("addPinModal.fileChosen", evt.target);
|
||||
}
|
||||
});
|
||||
|
||||
app.addComponent('addPinModal', (store) => { return new Reef("#addPinModal", {
|
||||
|
||||
store: store,
|
||||
|
|
@ -109,8 +193,11 @@ app.addComponent('addPinModal', (store) => { return new Reef("#addPinModal", {
|
|||
let imagePlaceholder = 'data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22300%22%20height%3D%22300%22%3E%3Crect%20x%3D%222%22%20y%3D%222%22%20width%3D%22300%22%20height%3D%22300%22%20style%3D%22fill%3A%23dedede%3B%22%2F%3E%3Ctext%20x%3D%2250%25%22%20y%3D%2250%25%22%20font-size%3D%2218%22%20text-anchor%3D%22middle%22%20alignment-baseline%3D%22middle%22%20font-family%3D%22monospace%2C%20sans-serif%22%20fill%3D%22%23555555%22%3Eimage%3C%2Ftext%3E%3C%2Fsvg%3E';
|
||||
|
||||
let options = "";
|
||||
|
||||
for ( let i = 0; i < data.boards.length; ++i ){
|
||||
options += `<option value="${data.boards[i].id}">${data.boards[i].name}</option>`;
|
||||
if ( data.showHiddenBoards || !data.boards[i].hidden ){
|
||||
options += `<option value="${data.boards[i].id}">${data.boards[i].name}</option>`;
|
||||
}
|
||||
}
|
||||
|
||||
let newBoardField = '';
|
||||
|
|
@ -134,6 +221,17 @@ app.addComponent('addPinModal', (store) => { return new Reef("#addPinModal", {
|
|||
<button class="delete" aria-label="close" data-onclick="addPinModal.close"></button>
|
||||
</header>
|
||||
<section class="modal-card-body">
|
||||
${ !data.addPinModal.didYouKnowDragAndDropMessageDisabled ? /*html*/`
|
||||
<div class="message is-success">
|
||||
<div class="message-header">
|
||||
<p>Did you know?</p>
|
||||
<button type="button" class="delete" aria-label="delete" label="Don't show again" data-onclick="addPinModal.disableDidYouKnowDragAndDropMessage"></button>
|
||||
</div>
|
||||
<div class="message-body">
|
||||
Did you know? You can now upload files to an existing board by drag-and-drop!
|
||||
</div>
|
||||
</div>
|
||||
` : ''}
|
||||
<div class="add-pin-flex">
|
||||
<div class="add-pin-flex-left">
|
||||
<img id="add-pin-modal-img" src="${data.addPinModal.previewImageUrl ? data.addPinModal.previewImageUrl : imagePlaceholder}" />
|
||||
|
|
@ -141,6 +239,8 @@ app.addComponent('addPinModal', (store) => { return new Reef("#addPinModal", {
|
|||
<div class="add-pin-flex-right">
|
||||
<form>
|
||||
|
||||
|
||||
|
||||
<div class="field">
|
||||
<label class="label">Board</label>
|
||||
<div class="select">
|
||||
|
|
@ -153,13 +253,31 @@ app.addComponent('addPinModal', (store) => { return new Reef("#addPinModal", {
|
|||
|
||||
${newBoardField}
|
||||
|
||||
${ data.addPinModal.uploadFile ? /*html*/`
|
||||
<div class="field">
|
||||
<label class="label">Image File</label>
|
||||
<div class="control">
|
||||
<span>${data.addPinModal.uploadFile.name}</span>
|
||||
<button type="button" class="delete" aria-label="remove" data-onclick="addPinModal.removeUploadFile"></button>
|
||||
</div>
|
||||
</div>
|
||||
` :
|
||||
/*html*/`
|
||||
<div class="field">
|
||||
<label class="label">Image Url</label>
|
||||
<div class="control">
|
||||
<input class="input" type="text" data-bind="addPinModal.imageUrl" data-onblur="addPinModal.updatePreview"/>
|
||||
<input class="input" type="text" data-bind="addPinModal.imageUrl" data-onblur="addPinModal.updatePreview" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<lable class="label">or choose file</lable>
|
||||
<div class="control">
|
||||
<input class="input" type="file" id="fileInput" />
|
||||
</div>
|
||||
</div>
|
||||
`}
|
||||
|
||||
<div class="field">
|
||||
<label class="label">Website Url</label>
|
||||
<div class="control">
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ app.addGetter('editPinModal.isValid', (data) => {
|
|||
|
||||
let pin = getPinById(data.editPinModal.pin.id);
|
||||
|
||||
if ( pin.siteUrl == data.editPinModal.pin.siteUrl &&
|
||||
if ( pin && pin.siteUrl == data.editPinModal.pin.siteUrl &&
|
||||
pin.description == data.editPinModal.pin.description &&
|
||||
pin.boardId == data.editPinModal.pin.boardId ){
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ app.addComponent('navbar', (store) => { return new Reef("#navbar", {
|
|||
}
|
||||
|
||||
let settingsItem = "";
|
||||
if (data.user.admin == 1){
|
||||
if (data.user && data.user.admin == 1){
|
||||
settingsItem = `
|
||||
<a class="navbar-item has-text-right" href="./settings">
|
||||
<span>tinypin settings</span>
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ Reef.databind = function(reef){
|
|||
} else {
|
||||
elem.checked = false;
|
||||
}
|
||||
|
||||
} else {
|
||||
elem.value = val;
|
||||
}
|
||||
|
|
@ -170,7 +171,7 @@ Reef.databind = function(reef){
|
|||
}
|
||||
|
||||
// multiple selects need special handling
|
||||
if ( target.tagName == 'SELECT' && target.matches("[multiple]") ){
|
||||
else if ( target.tagName == 'SELECT' && target.matches("[multiple]") ){
|
||||
val = [];
|
||||
let options = target.querySelectorAll("option");
|
||||
for ( let i = 0; i < options.length; ++i ){
|
||||
|
|
|
|||
|
|
@ -58,7 +58,11 @@ function getPinIndexById(id){
|
|||
}
|
||||
|
||||
function getPinById(id){
|
||||
return store.data.board.pins[getPinIndexById(id)];
|
||||
try{
|
||||
return store.data.board.pins[getPinIndexById(id)];
|
||||
} catch (e){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function sleep(ms){ return new Promise((resolve) => setTimeout(resolve, ms)); }
|
||||
|
|
|
|||
264
package-lock.json
generated
264
package-lock.json
generated
|
|
@ -14,6 +14,7 @@
|
|||
"eta": "^1.12.1",
|
||||
"express": "^4.17.1",
|
||||
"express-ws": "^4.0.0",
|
||||
"multer": "^1.4.3",
|
||||
"node-fetch": "^2.6.1",
|
||||
"sharp": "^0.27.0",
|
||||
"yargs": "^16.2.0"
|
||||
|
|
@ -69,6 +70,11 @@
|
|||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"node_modules/append-field": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz",
|
||||
"integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY="
|
||||
},
|
||||
"node_modules/aproba": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
|
||||
|
|
@ -326,6 +332,44 @@
|
|||
"ieee754": "^1.1.13"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
|
||||
},
|
||||
"node_modules/busboy": {
|
||||
"version": "0.2.14",
|
||||
"resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz",
|
||||
"integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=",
|
||||
"dependencies": {
|
||||
"dicer": "0.2.5",
|
||||
"readable-stream": "1.1.x"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/busboy/node_modules/isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
|
||||
},
|
||||
"node_modules/busboy/node_modules/readable-stream": {
|
||||
"version": "1.1.14",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
|
||||
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
|
||||
"dependencies": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.1",
|
||||
"isarray": "0.0.1",
|
||||
"string_decoder": "~0.10.x"
|
||||
}
|
||||
},
|
||||
"node_modules/busboy/node_modules/string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
|
||||
},
|
||||
"node_modules/bytes": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
|
||||
|
|
@ -428,6 +472,20 @@
|
|||
"simple-swizzle": "^0.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-stream": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
|
||||
"integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
|
||||
"engines": [
|
||||
"node >= 0.8"
|
||||
],
|
||||
"dependencies": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^2.2.2",
|
||||
"typedarray": "^0.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||
|
|
@ -541,6 +599,39 @@
|
|||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/dicer": {
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz",
|
||||
"integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=",
|
||||
"dependencies": {
|
||||
"readable-stream": "1.1.x",
|
||||
"streamsearch": "0.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dicer/node_modules/isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
|
||||
},
|
||||
"node_modules/dicer/node_modules/readable-stream": {
|
||||
"version": "1.1.14",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
|
||||
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
|
||||
"dependencies": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.1",
|
||||
"isarray": "0.0.1",
|
||||
"string_decoder": "~0.10.x"
|
||||
}
|
||||
},
|
||||
"node_modules/dicer/node_modules/string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
|
||||
},
|
||||
"node_modules/ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
|
|
@ -909,6 +1000,17 @@
|
|||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
},
|
||||
"node_modules/mkdirp": {
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.5"
|
||||
},
|
||||
"bin": {
|
||||
"mkdirp": "bin/cmd.js"
|
||||
}
|
||||
},
|
||||
"node_modules/mkdirp-classic": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
|
||||
|
|
@ -919,6 +1021,24 @@
|
|||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"node_modules/multer": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/multer/-/multer-1.4.3.tgz",
|
||||
"integrity": "sha512-np0YLKncuZoTzufbkM6wEKp68EhWJXcU6fq6QqrSwkckd2LlMgd1UqhUJLj6NS/5sZ8dE8LYDWslsltJznnXlg==",
|
||||
"dependencies": {
|
||||
"append-field": "^1.0.0",
|
||||
"busboy": "^0.2.11",
|
||||
"concat-stream": "^1.5.2",
|
||||
"mkdirp": "^0.5.4",
|
||||
"object-assign": "^4.1.1",
|
||||
"on-finished": "^2.3.0",
|
||||
"type-is": "^1.6.4",
|
||||
"xtend": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/napi-build-utils": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
|
||||
|
|
@ -1341,6 +1461,14 @@
|
|||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/streamsearch": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
|
||||
"integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
|
|
@ -1451,6 +1579,11 @@
|
|||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/typedarray": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
|
||||
},
|
||||
"node_modules/unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
|
|
@ -1562,6 +1695,14 @@
|
|||
"async-limiter": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/xtend": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
||||
"engines": {
|
||||
"node": ">=0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/y18n": {
|
||||
"version": "5.0.5",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz",
|
||||
|
|
@ -1679,6 +1820,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"append-field": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz",
|
||||
"integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY="
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
|
||||
|
|
@ -1869,6 +2015,43 @@
|
|||
"ieee754": "^1.1.13"
|
||||
}
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
|
||||
},
|
||||
"busboy": {
|
||||
"version": "0.2.14",
|
||||
"resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz",
|
||||
"integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=",
|
||||
"requires": {
|
||||
"dicer": "0.2.5",
|
||||
"readable-stream": "1.1.x"
|
||||
},
|
||||
"dependencies": {
|
||||
"isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "1.1.14",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
|
||||
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.1",
|
||||
"isarray": "0.0.1",
|
||||
"string_decoder": "~0.10.x"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
|
||||
}
|
||||
}
|
||||
},
|
||||
"bytes": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
|
||||
|
|
@ -1955,6 +2138,17 @@
|
|||
"simple-swizzle": "^0.2.2"
|
||||
}
|
||||
},
|
||||
"concat-stream": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
|
||||
"integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
|
||||
"requires": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^2.2.2",
|
||||
"typedarray": "^0.0.6"
|
||||
}
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||
|
|
@ -2038,6 +2232,38 @@
|
|||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
|
||||
"integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups="
|
||||
},
|
||||
"dicer": {
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz",
|
||||
"integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=",
|
||||
"requires": {
|
||||
"readable-stream": "1.1.x",
|
||||
"streamsearch": "0.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "1.1.14",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
|
||||
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.1",
|
||||
"isarray": "0.0.1",
|
||||
"string_decoder": "~0.10.x"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
|
||||
}
|
||||
}
|
||||
},
|
||||
"ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
|
|
@ -2318,6 +2544,14 @@
|
|||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||
"requires": {
|
||||
"minimist": "^1.2.5"
|
||||
}
|
||||
},
|
||||
"mkdirp-classic": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
|
||||
|
|
@ -2328,6 +2562,21 @@
|
|||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"multer": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/multer/-/multer-1.4.3.tgz",
|
||||
"integrity": "sha512-np0YLKncuZoTzufbkM6wEKp68EhWJXcU6fq6QqrSwkckd2LlMgd1UqhUJLj6NS/5sZ8dE8LYDWslsltJznnXlg==",
|
||||
"requires": {
|
||||
"append-field": "^1.0.0",
|
||||
"busboy": "^0.2.11",
|
||||
"concat-stream": "^1.5.2",
|
||||
"mkdirp": "^0.5.4",
|
||||
"object-assign": "^4.1.1",
|
||||
"on-finished": "^2.3.0",
|
||||
"type-is": "^1.6.4",
|
||||
"xtend": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"napi-build-utils": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
|
||||
|
|
@ -2652,6 +2901,11 @@
|
|||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
||||
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
|
||||
},
|
||||
"streamsearch": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
|
||||
"integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
|
|
@ -2740,6 +2994,11 @@
|
|||
"mime-types": "~2.1.24"
|
||||
}
|
||||
},
|
||||
"typedarray": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
|
||||
},
|
||||
"unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
|
|
@ -2826,6 +3085,11 @@
|
|||
"async-limiter": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
|
||||
},
|
||||
"y18n": {
|
||||
"version": "5.0.5",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz",
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
"eta": "^1.12.1",
|
||||
"express": "^4.17.1",
|
||||
"express-ws": "^4.0.0",
|
||||
"multer": "^1.4.3",
|
||||
"node-fetch": "^2.6.1",
|
||||
"sharp": "^0.27.0",
|
||||
"yargs": "^16.2.0"
|
||||
|
|
|
|||
|
|
@ -8,6 +8,36 @@ function sendAuthCookie(res, c){
|
|||
res.cookie('s', tokenUtils.encrypt(c), {maxAge: 315569520000}); // 10 years
|
||||
}
|
||||
|
||||
function maybeGetUser(req){
|
||||
|
||||
if ( !req.cookies ){
|
||||
return null;
|
||||
}
|
||||
|
||||
// if we made it this far, we're eady to check for the cookie
|
||||
let s = req.cookies.s;
|
||||
|
||||
// TODO: should probably check if the user's access has been revoked,
|
||||
// but we currently don't allow deleting users anyway. A key rotation would
|
||||
// be the other solution, but that would log out all users and require new tokens
|
||||
// to be created.
|
||||
if ( s ){
|
||||
try {
|
||||
s = tokenUtils.decrypt(s);
|
||||
if ( s.i && s.u ){
|
||||
return {
|
||||
id: s.i,
|
||||
name: s.u
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(`error parsing cookie: `, err);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports = async (req, res, next) => {
|
||||
|
||||
// we will also accept the auth token in the x-api-key header
|
||||
|
|
@ -60,6 +90,13 @@ module.exports = async (req, res, next) => {
|
|||
next();
|
||||
return;
|
||||
} if ( req.method == "GET" && req.originalUrl == "/login" ){
|
||||
|
||||
|
||||
if ( maybeGetUser(req) ){
|
||||
res.redirect("./");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("login");
|
||||
// res.type("html").sendFile(path.resolve('./templates/login.html'));
|
||||
res.render("login", { registerEnabled: dao.getProperty("registerEnabled") });
|
||||
|
|
@ -135,26 +172,27 @@ module.exports = async (req, res, next) => {
|
|||
return;
|
||||
}
|
||||
|
||||
// if we made it this far, we're eady to check for the cookie
|
||||
let s = req.cookies.s;
|
||||
// // if we made it this far, we're eady to check for the cookie
|
||||
// let s = req.cookies.s;
|
||||
|
||||
// TODO: should probably check if the user's access has been revoked,
|
||||
// but we currently don't allow deleting users anyway. A key rotation would
|
||||
// be the other solution, but that would log out all users and require new tokens
|
||||
// to be created.
|
||||
if ( s ){
|
||||
try {
|
||||
s = tokenUtils.decrypt(s);
|
||||
if ( s.i && s.u ){
|
||||
req.user = {
|
||||
id: s.i,
|
||||
name: s.u
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`error parsing cookie: `, err);
|
||||
}
|
||||
}
|
||||
// // TODO: should probably check if the user's access has been revoked,
|
||||
// // but we currently don't allow deleting users anyway. A key rotation would
|
||||
// // be the other solution, but that would log out all users and require new tokens
|
||||
// // to be created.
|
||||
// if ( s ){
|
||||
// try {
|
||||
// s = tokenUtils.decrypt(s);
|
||||
// if ( s.i && s.u ){
|
||||
// req.user = {
|
||||
// id: s.i,
|
||||
// name: s.u
|
||||
// }
|
||||
// }
|
||||
// } catch (err) {
|
||||
// console.error(`error parsing cookie: `, err);
|
||||
// }
|
||||
// }
|
||||
req.user = maybeGetUser(req);
|
||||
|
||||
if ( !req.user ){
|
||||
res.redirect("/login");
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
const yargs = require('yargs');
|
||||
const express = require('express');
|
||||
const bodyParser = require('body-parser');
|
||||
const multer = require("multer")
|
||||
const path = require('path');
|
||||
const cookieParser = require('cookie-parser');
|
||||
const tokenUtil = require('./token-utils.js');
|
||||
|
|
@ -10,6 +11,9 @@ const imageUtils = require('./image-utils.js');
|
|||
var eta = require("eta");
|
||||
const tokenUtils = require('./token-utils.js');
|
||||
|
||||
// consider using temp files, but we're going to limit the size so should be ok
|
||||
const upload = multer({storage:multer.memoryStorage(), limits: {fileSize: 26214400, files: 1}}); // 1 - 25MB file
|
||||
|
||||
module.exports = async () => {
|
||||
|
||||
process.on('SIGINT', () => {
|
||||
|
|
@ -340,6 +344,7 @@ module.exports = async () => {
|
|||
res.status(200).send({t: token});
|
||||
});
|
||||
|
||||
// handle raw uploads for pin creation
|
||||
app.post("/up", async (req, res) => {
|
||||
|
||||
try {
|
||||
|
|
@ -358,7 +363,7 @@ module.exports = async () => {
|
|||
board = dao.createBoard(req.user.id, boardName, 0);
|
||||
}
|
||||
|
||||
let pin = dao.createPin(req.user.id, board.id, null, null, null, null, image.original.height, image.original.width, image.thumbnail.height, image.thumbnailWidth);
|
||||
let pin = dao.createPin(req.user.id, board.id, null, null, null, null, image.original.height, image.original.width, image.thumbnail.height, image.thumbnail.height);
|
||||
|
||||
await imageUtils.saveImage(req.user.id, pin.id, image);
|
||||
|
||||
|
|
@ -371,6 +376,38 @@ module.exports = async () => {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
// handle multipart uploads for pin creation
|
||||
app.post("/multiup", upload.single('file'), async(req, res) => {
|
||||
try {
|
||||
|
||||
let image = await imageUtils.processImage(req.file.buffer); // file.buffer only works with the Memory store for multer.
|
||||
|
||||
let boardId = req.body.boardId;
|
||||
|
||||
let board = null;
|
||||
|
||||
if ( boardId == "new" ){
|
||||
board = dao.createBoard(req.user.id, req.body.newBoardName, 0);
|
||||
} else {
|
||||
board = dao.getBoard(req.user.id, boardId);
|
||||
}
|
||||
|
||||
console.log(image);
|
||||
|
||||
let pin = dao.createPin(req.user.id, board.id, null, req.body.siteUrl, req.body.description, null, image.original.height, image.original.width, image.thumbnail.height, image.thumbnail.height);
|
||||
|
||||
await imageUtils.saveImage(req.user.id, pin.id, image);
|
||||
|
||||
broadcast(req.user.id, {updateBoard:board.id});
|
||||
res.status(200).send(pin);
|
||||
|
||||
} catch (err) {
|
||||
console.log(`Error creating pin via multipart upload`, err);
|
||||
res.status(500).send(SERVER_ERROR);
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/api/apikey", (req,res) => {
|
||||
let s = req.cookies['s'];
|
||||
console.log("s=" + s);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue