forked from cory/tildefriends
Modernize. All core JS is modules. var => let.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4155 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
parent
7091b6e6a5
commit
c692b1b1f8
52
core/auth.js
52
core/auth.js
@ -1,8 +1,8 @@
|
|||||||
import * as core from './core.js';
|
import * as core from './core.js';
|
||||||
import * as form from './form.js';
|
import * as form from './form.js';
|
||||||
|
|
||||||
var gTokens = {};
|
let gTokens = {};
|
||||||
var gDatabase = new Database("auth");
|
let gDatabase = new Database("auth");
|
||||||
|
|
||||||
const kRefreshInterval = 1 * 7 * 24 * 60 * 60 * 1000;
|
const kRefreshInterval = 1 * 7 * 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ function verifyPassword(password, hash) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function hashPassword(password) {
|
function hashPassword(password) {
|
||||||
var salt = bCrypt.gensalt(12);
|
let salt = bCrypt.gensalt(12);
|
||||||
return bCrypt.hashpw(password, salt);
|
return bCrypt.hashpw(password, salt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,14 +99,14 @@ function makeAdministrator(name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getCookies(headers) {
|
function getCookies(headers) {
|
||||||
var cookies = {};
|
let cookies = {};
|
||||||
|
|
||||||
if (headers.cookie) {
|
if (headers.cookie) {
|
||||||
var parts = headers.cookie.split(/,|;/);
|
let parts = headers.cookie.split(/,|;/);
|
||||||
for (var i in parts) {
|
for (let i in parts) {
|
||||||
var equals = parts[i].indexOf("=");
|
let equals = parts[i].indexOf("=");
|
||||||
var name = parts[i].substring(0, equals).trim();
|
let name = parts[i].substring(0, equals).trim();
|
||||||
var value = parts[i].substring(equals + 1).trim();
|
let value = parts[i].substring(equals + 1).trim();
|
||||||
cookies[name] = value;
|
cookies[name] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,18 +115,18 @@ function getCookies(headers) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handler(request, response) {
|
function handler(request, response) {
|
||||||
var session = getCookies(request.headers).session;
|
let session = getCookies(request.headers).session;
|
||||||
if (request.uri == "/login") {
|
if (request.uri == "/login") {
|
||||||
var sessionIsNew = false;
|
let sessionIsNew = false;
|
||||||
var loginError;
|
let loginError;
|
||||||
|
|
||||||
var formData = form.decodeForm(request.query);
|
let formData = form.decodeForm(request.query);
|
||||||
|
|
||||||
if (request.method == "POST" || formData.submit) {
|
if (request.method == "POST" || formData.submit) {
|
||||||
sessionIsNew = true;
|
sessionIsNew = true;
|
||||||
formData = form.decodeForm(utf8Decode(request.body), formData);
|
formData = form.decodeForm(utf8Decode(request.body), formData);
|
||||||
if (formData.submit == "Login") {
|
if (formData.submit == "Login") {
|
||||||
var account = gDatabase.get("user:" + formData.name);
|
let account = gDatabase.get("user:" + formData.name);
|
||||||
account = account ? JSON.parse(account) : account;
|
account = account ? JSON.parse(account) : account;
|
||||||
if (formData.register == "1") {
|
if (formData.register == "1") {
|
||||||
if (!account &&
|
if (!account &&
|
||||||
@ -171,15 +171,15 @@ function handler(request, response) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var cookie = `session=${session}; path=/; Max-Age=${kRefreshInterval}; Secure; SameSite=Strict`;
|
let cookie = `session=${session}; path=/; Max-Age=${kRefreshInterval}; Secure; SameSite=Strict`;
|
||||||
var entry = readSession(session);
|
let entry = readSession(session);
|
||||||
if (entry && formData.return) {
|
if (entry && formData.return) {
|
||||||
response.writeHead(303, {"Location": formData.return, "Set-Cookie": cookie});
|
response.writeHead(303, {"Location": formData.return, "Set-Cookie": cookie});
|
||||||
response.end();
|
response.end();
|
||||||
} else {
|
} else {
|
||||||
File.readFile("core/auth.html").then(function(data) {
|
File.readFile("core/auth.html").then(function(data) {
|
||||||
var html = utf8Decode(data);
|
let html = utf8Decode(data);
|
||||||
var contents = "";
|
let contents = "";
|
||||||
|
|
||||||
if (entry) {
|
if (entry) {
|
||||||
if (sessionIsNew) {
|
if (sessionIsNew) {
|
||||||
@ -216,7 +216,7 @@ function handler(request, response) {
|
|||||||
contents += '</div>\n';
|
contents += '</div>\n';
|
||||||
contents += '</form>';
|
contents += '</form>';
|
||||||
}
|
}
|
||||||
var text = html.replace("<!--SESSION-->", contents);
|
let text = html.replace("<!--SESSION-->", contents);
|
||||||
response.writeHead(200, {"Content-Type": "text/html; charset=utf-8", "Set-Cookie": cookie, "Content-Length": text.length});
|
response.writeHead(200, {"Content-Type": "text/html; charset=utf-8", "Set-Cookie": cookie, "Content-Length": text.length});
|
||||||
response.end(text);
|
response.end(text);
|
||||||
}).catch(function(error) {
|
}).catch(function(error) {
|
||||||
@ -234,8 +234,8 @@ function handler(request, response) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getPermissions(session) {
|
function getPermissions(session) {
|
||||||
var permissions;
|
let permissions;
|
||||||
var entry = readSession(session);
|
let entry = readSession(session);
|
||||||
if (entry) {
|
if (entry) {
|
||||||
permissions = getPermissionsForUser(entry.name);
|
permissions = getPermissionsForUser(entry.name);
|
||||||
permissions.authenticated = entry.name !== "guest";
|
permissions.authenticated = entry.name !== "guest";
|
||||||
@ -244,9 +244,9 @@ function getPermissions(session) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getPermissionsForUser(userName) {
|
function getPermissionsForUser(userName) {
|
||||||
var permissions = {};
|
let permissions = {};
|
||||||
if (core.globalSettings && core.globalSettings.permissions && core.globalSettings.permissions[userName]) {
|
if (core.globalSettings && core.globalSettings.permissions && core.globalSettings.permissions[userName]) {
|
||||||
for (var i in core.globalSettings.permissions[userName]) {
|
for (let i in core.globalSettings.permissions[userName]) {
|
||||||
permissions[core.globalSettings.permissions[userName][i]] = true;
|
permissions[core.globalSettings.permissions[userName][i]] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,9 +254,9 @@ function getPermissionsForUser(userName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function query(headers) {
|
function query(headers) {
|
||||||
var session = getCookies(headers).session;
|
let session = getCookies(headers).session;
|
||||||
var entry;
|
let entry;
|
||||||
var autologin = tildefriends.args.autologin;
|
let autologin = tildefriends.args.autologin;
|
||||||
if (entry = autologin ? {name: autologin} : readSession(session)) {
|
if (entry = autologin ? {name: autologin} : readSession(session)) {
|
||||||
return {
|
return {
|
||||||
session: entry,
|
session: entry,
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let gSocket;
|
let gSocket;
|
||||||
let gCredentials;
|
let gCredentials;
|
||||||
let gPermissions;
|
let gPermissions;
|
||||||
@ -952,6 +950,27 @@ window.addEventListener("load", function() {
|
|||||||
window.addEventListener("message", message, false);
|
window.addEventListener("message", message, false);
|
||||||
window.addEventListener("online", connectSocket);
|
window.addEventListener("online", connectSocket);
|
||||||
document.getElementById("name").value = window.location.pathname;
|
document.getElementById("name").value = window.location.pathname;
|
||||||
|
document.getElementById('edit_link').addEventListener('click', function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
toggleEdit();
|
||||||
|
});
|
||||||
|
document.getElementById('show_permissions_link').addEventListener('click', () => showPermissions());
|
||||||
|
document.getElementById('files_hide').addEventListener('click', () => hideFiles());
|
||||||
|
document.getElementById('files_show').addEventListener('click', () => showFiles());
|
||||||
|
document.getElementById('closeStats').addEventListener('click', () => closeStats());
|
||||||
|
document.getElementById('closeEditor').addEventListener('click', () => closeEditor());
|
||||||
|
document.getElementById('save').addEventListener('click', () => save());
|
||||||
|
document.getElementById('delete').addEventListener('click', () => deleteApp());
|
||||||
|
document.getElementById('trace_button').addEventListener('click', function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
trace();
|
||||||
|
});
|
||||||
|
document.getElementById('stats_button').addEventListener('click', function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
toggleStats();
|
||||||
|
});
|
||||||
|
document.getElementById('new_file_button').addEventListener('click', () => newFile());
|
||||||
|
document.getElementById('remove_file_button').addEventListener('click', () => removeFile());
|
||||||
for (let tag of document.getElementsByTagName('a')) {
|
for (let tag of document.getElementsByTagName('a')) {
|
||||||
if (tag.accessKey) {
|
if (tag.accessKey) {
|
||||||
tag.classList.add('tooltip_parent');
|
tag.classList.add('tooltip_parent');
|
||||||
|
152
core/core.js
152
core/core.js
@ -2,9 +2,9 @@ import * as auth from './auth.js';
|
|||||||
import * as app from './app.js';
|
import * as app from './app.js';
|
||||||
import * as httpd from './httpd.js';
|
import * as httpd from './httpd.js';
|
||||||
|
|
||||||
var gProcessIndex = 0;
|
let gProcessIndex = 0;
|
||||||
var gProcesses = {};
|
let gProcesses = {};
|
||||||
var gStatsTimer = false;
|
let gStatsTimer = false;
|
||||||
|
|
||||||
const k_global_settings = {
|
const k_global_settings = {
|
||||||
index: {
|
index: {
|
||||||
@ -34,20 +34,20 @@ const k_global_settings = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
var gGlobalSettings = {
|
let gGlobalSettings = {
|
||||||
index: "/~core/apps/",
|
index: "/~core/apps/",
|
||||||
};
|
};
|
||||||
|
|
||||||
var kGlobalSettingsFile = "data/global/settings.json";
|
let kGlobalSettingsFile = "data/global/settings.json";
|
||||||
|
|
||||||
var kPingInterval = 60 * 1000;
|
let kPingInterval = 60 * 1000;
|
||||||
|
|
||||||
function printError(out, error) {
|
function printError(out, error) {
|
||||||
if (error.stackTrace) {
|
if (error.stackTrace) {
|
||||||
out.print(error.fileName + ":" + error.lineNumber + ": " + error.message);
|
out.print(error.fileName + ":" + error.lineNumber + ": " + error.message);
|
||||||
out.print(error.stackTrace);
|
out.print(error.stackTrace);
|
||||||
} else {
|
} else {
|
||||||
for (var i in error) {
|
for (let i in error) {
|
||||||
out.print(i);
|
out.print(i);
|
||||||
}
|
}
|
||||||
out.print(error.toString());
|
out.print(error.toString());
|
||||||
@ -55,9 +55,9 @@ function printError(out, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function invoke(handlers, argv) {
|
function invoke(handlers, argv) {
|
||||||
var promises = [];
|
let promises = [];
|
||||||
if (handlers) {
|
if (handlers) {
|
||||||
for (var i = 0; i < handlers.length; ++i) {
|
for (let i = 0; i < handlers.length; ++i) {
|
||||||
try {
|
try {
|
||||||
promises.push(handlers[i](...argv));
|
promises.push(handlers[i](...argv));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -71,9 +71,9 @@ function invoke(handlers, argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function broadcastEvent(eventName, argv) {
|
function broadcastEvent(eventName, argv) {
|
||||||
var promises = [];
|
let promises = [];
|
||||||
for (var i in gProcesses) {
|
for (let i in gProcesses) {
|
||||||
var process = gProcesses[i];
|
let process = gProcesses[i];
|
||||||
if (process.eventHandlers[eventName]) {
|
if (process.eventHandlers[eventName]) {
|
||||||
promises.push(invoke(process.eventHandlers[eventName], argv));
|
promises.push(invoke(process.eventHandlers[eventName], argv));
|
||||||
}
|
}
|
||||||
@ -82,14 +82,14 @@ function broadcastEvent(eventName, argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function broadcast(message) {
|
function broadcast(message) {
|
||||||
var sender = this;
|
let sender = this;
|
||||||
var promises = [];
|
let promises = [];
|
||||||
for (var i in gProcesses) {
|
for (let i in gProcesses) {
|
||||||
var process = gProcesses[i];
|
let process = gProcesses[i];
|
||||||
if (process != sender
|
if (process != sender
|
||||||
&& process.packageOwner == sender.packageOwner
|
&& process.packageOwner == sender.packageOwner
|
||||||
&& process.packageName == sender.packageName) {
|
&& process.packageName == sender.packageName) {
|
||||||
var from = getUser(process, sender);
|
let from = getUser(process, sender);
|
||||||
promises.push(postMessageInternal(from, process, message));
|
promises.push(postMessageInternal(from, process, message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,9 +119,9 @@ function getApps(user, process) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (user) {
|
if (user) {
|
||||||
var db = new Database(user);
|
let db = new Database(user);
|
||||||
try {
|
try {
|
||||||
var names = JSON.parse(db.get('apps'));
|
let names = JSON.parse(db.get('apps'));
|
||||||
return Object.fromEntries(names.map(name => [name, db.get('path:' + name)]));
|
return Object.fromEntries(names.map(name => [name, db.get('path:' + name)]));
|
||||||
} catch {
|
} catch {
|
||||||
}
|
}
|
||||||
@ -136,9 +136,9 @@ function postMessageInternal(from, to, message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getSessionProcessBlob(blobId, session, options) {
|
async function getSessionProcessBlob(blobId, session, options) {
|
||||||
var actualOptions = {timeout: kPingInterval};
|
let actualOptions = {timeout: kPingInterval};
|
||||||
if (options) {
|
if (options) {
|
||||||
for (var i in options) {
|
for (let i in options) {
|
||||||
actualOptions[i] = options[i];
|
actualOptions[i] = options[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -148,7 +148,7 @@ async function getSessionProcessBlob(blobId, session, options) {
|
|||||||
let gManifestCache = {};
|
let gManifestCache = {};
|
||||||
|
|
||||||
async function getProcessBlob(blobId, key, options) {
|
async function getProcessBlob(blobId, key, options) {
|
||||||
var process = gProcesses[key];
|
let process = gProcesses[key];
|
||||||
if (!process
|
if (!process
|
||||||
&& !(options && "create" in options && !options.create)) {
|
&& !(options && "create" in options && !options.create)) {
|
||||||
try {
|
try {
|
||||||
@ -165,8 +165,8 @@ async function getProcessBlob(blobId, key, options) {
|
|||||||
process.lastPing = null;
|
process.lastPing = null;
|
||||||
process.timeout = options.timeout;
|
process.timeout = options.timeout;
|
||||||
process.stats = false;
|
process.stats = false;
|
||||||
var resolveReady;
|
let resolveReady;
|
||||||
var rejectReady;
|
let rejectReady;
|
||||||
process.ready = new Promise(function(resolve, reject) {
|
process.ready = new Promise(function(resolve, reject) {
|
||||||
resolveReady = resolve;
|
resolveReady = resolve;
|
||||||
rejectReady = reject;
|
rejectReady = reject;
|
||||||
@ -177,7 +177,7 @@ async function getProcessBlob(blobId, key, options) {
|
|||||||
process.task = null;
|
process.task = null;
|
||||||
delete gProcesses[key];
|
delete gProcesses[key];
|
||||||
};
|
};
|
||||||
var imports = {
|
let imports = {
|
||||||
'core': {
|
'core': {
|
||||||
'broadcast': broadcast.bind(process),
|
'broadcast': broadcast.bind(process),
|
||||||
'register': function(eventName, handler) {
|
'register': function(eventName, handler) {
|
||||||
@ -352,11 +352,11 @@ async function getProcessBlob(blobId, key, options) {
|
|||||||
process.credentials.session &&
|
process.credentials.session &&
|
||||||
process.credentials.session.name) {
|
process.credentials.session.name) {
|
||||||
imports.database = function(key) {
|
imports.database = function(key) {
|
||||||
var db = new Database(process.credentials.session.name + ':' + key);
|
let db = new Database(process.credentials.session.name + ':' + key);
|
||||||
return Object.fromEntries(Object.keys(db).map(x => [x, db[x].bind(db)]));
|
return Object.fromEntries(Object.keys(db).map(x => [x, db[x].bind(db)]));
|
||||||
};
|
};
|
||||||
imports.my_shared_database = function(packageName, key) {
|
imports.my_shared_database = function(packageName, key) {
|
||||||
var db = new Database(':shared:' + process.credentials.session.name + ':' + packageName + ':' + key);
|
let db = new Database(':shared:' + process.credentials.session.name + ':' + packageName + ':' + key);
|
||||||
return Object.fromEntries(Object.keys(db).map(x => [x, db[x].bind(db)]));
|
return Object.fromEntries(Object.keys(db).map(x => [x, db[x].bind(db)]));
|
||||||
};
|
};
|
||||||
imports.databases = function() {
|
imports.databases = function() {
|
||||||
@ -365,7 +365,7 @@ async function getProcessBlob(blobId, key, options) {
|
|||||||
}
|
}
|
||||||
if (options.packageOwner && options.packageName) {
|
if (options.packageOwner && options.packageName) {
|
||||||
imports.shared_database = function(key) {
|
imports.shared_database = function(key) {
|
||||||
var db = new Database(':shared:' + options.packageOwner + ':' + options.packageName + ':' + key);
|
let db = new Database(':shared:' + options.packageOwner + ':' + options.packageName + ':' + key);
|
||||||
return Object.fromEntries(Object.keys(db).map(x => [x, db[x].bind(db)]));
|
return Object.fromEntries(Object.keys(db).map(x => [x, db[x].bind(db)]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -380,14 +380,14 @@ async function getProcessBlob(blobId, key, options) {
|
|||||||
process.task.setImports(imports);
|
process.task.setImports(imports);
|
||||||
process.task.activate();
|
process.task.activate();
|
||||||
let source = await getBlobOrContent(blobId);
|
let source = await getBlobOrContent(blobId);
|
||||||
var appSourceName = blobId;
|
let appSourceName = blobId;
|
||||||
var appSource = utf8Decode(source);
|
let appSource = utf8Decode(source);
|
||||||
try {
|
try {
|
||||||
var appObject = JSON.parse(appSource);
|
let appObject = JSON.parse(appSource);
|
||||||
if (appObject.type == "tildefriends-app") {
|
if (appObject.type == "tildefriends-app") {
|
||||||
appSourceName = 'app.js';
|
appSourceName = 'app.js';
|
||||||
var id = appObject.files[appSourceName];
|
let id = appObject.files[appSourceName];
|
||||||
var blob = await getBlobOrContent(id);
|
let blob = await getBlobOrContent(id);
|
||||||
appSource = utf8Decode(blob);
|
appSource = utf8Decode(blob);
|
||||||
await process.task.loadFile(['/tfrpc.js', await File.readFile('core/tfrpc.js')]);
|
await process.task.loadFile(['/tfrpc.js', await File.readFile('core/tfrpc.js')]);
|
||||||
await Promise.all(Object.keys(appObject.files).map(async function(f) {
|
await Promise.all(Object.keys(appObject.files).map(async function(f) {
|
||||||
@ -425,7 +425,7 @@ function setGlobalSettings(settings) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var kStaticFiles = [
|
let kStaticFiles = [
|
||||||
{uri: '/', path: 'index.html', type: 'text/html; charset=UTF-8'},
|
{uri: '/', path: 'index.html', type: 'text/html; charset=UTF-8'},
|
||||||
{uri: '/style.css', type: 'text/css; charset=UTF-8'},
|
{uri: '/style.css', type: 'text/css; charset=UTF-8'},
|
||||||
{uri: '/favicon.png', type: 'image/png'},
|
{uri: '/favicon.png', type: 'image/png'},
|
||||||
@ -436,8 +436,8 @@ var kStaticFiles = [
|
|||||||
|
|
||||||
function startsWithBytes(data, bytes) {
|
function startsWithBytes(data, bytes) {
|
||||||
if (data.byteLength >= bytes.length) {
|
if (data.byteLength >= bytes.length) {
|
||||||
var dataBytes = new Uint8Array(data.slice(0, bytes.length));
|
let dataBytes = new Uint8Array(data.slice(0, bytes.length));
|
||||||
for (var i = 0; i < bytes.length; i++) {
|
for (let i = 0; i < bytes.length; i++) {
|
||||||
if (dataBytes[i] != bytes[i] && bytes[i] !== null) {
|
if (dataBytes[i] != bytes[i] && bytes[i] !== null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -447,10 +447,10 @@ function startsWithBytes(data, bytes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function staticFileHandler(request, response, blobId, uri) {
|
async function staticFileHandler(request, response, blobId, uri) {
|
||||||
for (var i in kStaticFiles) {
|
for (let i in kStaticFiles) {
|
||||||
if (uri === kStaticFiles[i].uri) {
|
if (uri === kStaticFiles[i].uri) {
|
||||||
var path = kStaticFiles[i].path || uri.substring(1);
|
let path = kStaticFiles[i].path || uri.substring(1);
|
||||||
var type = kStaticFiles[i].type || guessType(path);
|
let type = kStaticFiles[i].type || guessType(path);
|
||||||
|
|
||||||
let stat = await File.stat('core/' + path);
|
let stat = await File.stat('core/' + path);
|
||||||
let id = `${stat.mtime}_${stat.size}`;
|
let id = `${stat.mtime}_${stat.size}`;
|
||||||
@ -459,7 +459,7 @@ async function staticFileHandler(request, response, blobId, uri) {
|
|||||||
response.writeHead(304, {});
|
response.writeHead(304, {});
|
||||||
response.end();
|
response.end();
|
||||||
} else {
|
} else {
|
||||||
var data = await File.readFile('core/' + path);
|
let data = await File.readFile('core/' + path);
|
||||||
response.writeHead(200, Object.assign(
|
response.writeHead(200, Object.assign(
|
||||||
{
|
{
|
||||||
'Content-Type': type,
|
'Content-Type': type,
|
||||||
@ -486,7 +486,7 @@ const k_mime_types = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
async function staticDirectoryHandler(request, response, directory, uri) {
|
async function staticDirectoryHandler(request, response, directory, uri) {
|
||||||
var filename = uri || 'index.html';
|
let filename = uri || 'index.html';
|
||||||
if (filename.indexOf('..') != -1) {
|
if (filename.indexOf('..') != -1) {
|
||||||
response.writeHead(404, {"Content-Type": "text/plain; charset=utf-8", "Content-Length": "File not found".length});
|
response.writeHead(404, {"Content-Type": "text/plain; charset=utf-8", "Content-Length": "File not found".length});
|
||||||
response.end("File not found");
|
response.end("File not found");
|
||||||
@ -501,7 +501,7 @@ async function staticDirectoryHandler(request, response, directory, uri) {
|
|||||||
response.writeHead(304, {});
|
response.writeHead(304, {});
|
||||||
response.end();
|
response.end();
|
||||||
} else {
|
} else {
|
||||||
var data = await File.readFile(directory + filename);
|
let data = await File.readFile(directory + filename);
|
||||||
response.writeHead(200, {
|
response.writeHead(200, {
|
||||||
'Content-Type': k_mime_types[filename.split('.').pop()] || 'text/plain',
|
'Content-Type': k_mime_types[filename.split('.').pop()] || 'text/plain',
|
||||||
'Content-Length': data.byteLength,
|
'Content-Length': data.byteLength,
|
||||||
@ -516,7 +516,7 @@ async function staticDirectoryHandler(request, response, directory, uri) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function wellKnownHandler(request, response, path) {
|
async function wellKnownHandler(request, response, path) {
|
||||||
var data = await File.readFile("data/global/.well-known/" + path);
|
let data = await File.readFile("data/global/.well-known/" + path);
|
||||||
if (data) {
|
if (data) {
|
||||||
response.writeHead(200, {"Content-Type": "text/plain", "Content-Length": data.length});
|
response.writeHead(200, {"Content-Type": "text/plain", "Content-Length": data.length});
|
||||||
response.end(data);
|
response.end(data);
|
||||||
@ -578,12 +578,12 @@ function guessType(path) {
|
|||||||
'js': 'text/javascript',
|
'js': 'text/javascript',
|
||||||
'svg': 'image/svg+xml',
|
'svg': 'image/svg+xml',
|
||||||
};
|
};
|
||||||
var extension = path.split('.').pop();
|
let extension = path.split('.').pop();
|
||||||
return k_extension_to_type[extension];
|
return k_extension_to_type[extension];
|
||||||
}
|
}
|
||||||
|
|
||||||
async function blobHandler(request, response, blobId, uri) {
|
async function blobHandler(request, response, blobId, uri) {
|
||||||
for (var i in kStaticFiles) {
|
for (let i in kStaticFiles) {
|
||||||
if (uri === kStaticFiles[i].uri && kStaticFiles[i].path) {
|
if (uri === kStaticFiles[i].uri && kStaticFiles[i].path) {
|
||||||
let stat = await File.stat('core/' + kStaticFiles[i].path);
|
let stat = await File.stat('core/' + kStaticFiles[i].path);
|
||||||
let id = `${stat.mtime}_${stat.size}`;
|
let id = `${stat.mtime}_${stat.size}`;
|
||||||
@ -592,7 +592,7 @@ async function blobHandler(request, response, blobId, uri) {
|
|||||||
response.writeHead(304, {});
|
response.writeHead(304, {});
|
||||||
response.end();
|
response.end();
|
||||||
} else {
|
} else {
|
||||||
var data = await File.readFile('core/' + kStaticFiles[i].path);
|
let data = await File.readFile('core/' + kStaticFiles[i].path);
|
||||||
response.writeHead(200, Object.assign(
|
response.writeHead(200, Object.assign(
|
||||||
{
|
{
|
||||||
'Content-Type': kStaticFiles[i].type,
|
'Content-Type': kStaticFiles[i].type,
|
||||||
@ -612,11 +612,12 @@ async function blobHandler(request, response, blobId, uri) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var process;
|
let process;
|
||||||
if (uri == "/view") {
|
if (uri == "/view") {
|
||||||
var data;
|
let data;
|
||||||
|
let match;
|
||||||
if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) {
|
if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) {
|
||||||
var id = await new Database(match[1]).get('path:' + match[2]);
|
let id = await new Database(match[1]).get('path:' + match[2]);
|
||||||
if (id) {
|
if (id) {
|
||||||
if (request.headers['if-none-match'] === '"' + id + '"') {
|
if (request.headers['if-none-match'] === '"' + id + '"') {
|
||||||
response.writeHead(304, {});
|
response.writeHead(304, {});
|
||||||
@ -624,7 +625,7 @@ async function blobHandler(request, response, blobId, uri) {
|
|||||||
} else {
|
} else {
|
||||||
data = await getBlobOrContent(id);
|
data = await getBlobOrContent(id);
|
||||||
if (match[3]) {
|
if (match[3]) {
|
||||||
var appObject = JSON.parse(data);
|
let appObject = JSON.parse(data);
|
||||||
data = appObject.files[match[3]];
|
data = appObject.files[match[3]];
|
||||||
}
|
}
|
||||||
sendData(response, data, undefined, {etag: '"' + id + '"'});
|
sendData(response, data, undefined, {etag: '"' + id + '"'});
|
||||||
@ -647,17 +648,17 @@ async function blobHandler(request, response, blobId, uri) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (uri == "/save") {
|
} else if (uri == "/save") {
|
||||||
var match;
|
let match;
|
||||||
if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) {
|
if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) {
|
||||||
let newBlobId = await ssb.blobStore(request.body);
|
let newBlobId = await ssb.blobStore(request.body);
|
||||||
var user = match[1];
|
let user = match[1];
|
||||||
var appName = match[2];
|
let appName = match[2];
|
||||||
var credentials = auth.query(request.headers);
|
let credentials = auth.query(request.headers);
|
||||||
if (credentials && credentials.session &&
|
if (credentials && credentials.session &&
|
||||||
(credentials.session.name == user ||
|
(credentials.session.name == user ||
|
||||||
(credentials.permissions.administration && user == 'core'))) {
|
(credentials.permissions.administration && user == 'core'))) {
|
||||||
var database = new Database(user);
|
let database = new Database(user);
|
||||||
var apps = new Set();
|
let apps = new Set();
|
||||||
let apps_original = database.get('apps');
|
let apps_original = database.get('apps');
|
||||||
try {
|
try {
|
||||||
apps = new Set(JSON.parse(apps_original));
|
apps = new Set(JSON.parse(apps_original));
|
||||||
@ -691,14 +692,14 @@ async function blobHandler(request, response, blobId, uri) {
|
|||||||
} else if (uri == "/delete") {
|
} else if (uri == "/delete") {
|
||||||
let match;
|
let match;
|
||||||
if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) {
|
if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) {
|
||||||
var user = match[1];
|
let user = match[1];
|
||||||
var appName = match[2];
|
let appName = match[2];
|
||||||
var credentials = auth.query(request.headers);
|
let credentials = auth.query(request.headers);
|
||||||
if (credentials && credentials.session &&
|
if (credentials && credentials.session &&
|
||||||
(credentials.session.name == user ||
|
(credentials.session.name == user ||
|
||||||
(credentials.permissions.administration && user == 'core'))) {
|
(credentials.permissions.administration && user == 'core'))) {
|
||||||
var database = new Database(user);
|
let database = new Database(user);
|
||||||
var apps = new Set();
|
let apps = new Set();
|
||||||
try {
|
try {
|
||||||
apps = new Set(JSON.parse(database.get('apps')));
|
apps = new Set(JSON.parse(database.get('apps')));
|
||||||
} catch {
|
} catch {
|
||||||
@ -717,12 +718,13 @@ async function blobHandler(request, response, blobId, uri) {
|
|||||||
response.writeHead(200, {"Content-Type": "text/plain; charset=utf-8"});
|
response.writeHead(200, {"Content-Type": "text/plain; charset=utf-8"});
|
||||||
response.end('OK');
|
response.end('OK');
|
||||||
} else {
|
} else {
|
||||||
var data;
|
let data;
|
||||||
var type;
|
let type;
|
||||||
var headers;
|
let headers;
|
||||||
|
let match;
|
||||||
if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) {
|
if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) {
|
||||||
var db = new Database(match[1]);
|
let db = new Database(match[1]);
|
||||||
var id = await db.get('path:' + match[2]);
|
let id = await db.get('path:' + match[2]);
|
||||||
if (id) {
|
if (id) {
|
||||||
if (request.headers['if-none-match'] && request.headers['if-none-match'] == '"' + id + '"') {
|
if (request.headers['if-none-match'] && request.headers['if-none-match'] == '"' + id + '"') {
|
||||||
headers = {
|
headers = {
|
||||||
@ -732,7 +734,7 @@ async function blobHandler(request, response, blobId, uri) {
|
|||||||
response.end();
|
response.end();
|
||||||
} else {
|
} else {
|
||||||
data = utf8Decode(await getBlobOrContent(id));
|
data = utf8Decode(await getBlobOrContent(id));
|
||||||
var appObject = JSON.parse(data);
|
let appObject = JSON.parse(data);
|
||||||
data = appObject.files[uri.substring(1)];
|
data = appObject.files[uri.substring(1)];
|
||||||
data = await getBlobOrContent(data);
|
data = await getBlobOrContent(data);
|
||||||
type = guessType(uri);
|
type = guessType(uri);
|
||||||
@ -747,7 +749,7 @@ async function blobHandler(request, response, blobId, uri) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
data = utf8Decode(await getBlobOrContent(blobId));
|
data = utf8Decode(await getBlobOrContent(blobId));
|
||||||
var appObject = JSON.parse(data);
|
let appObject = JSON.parse(data);
|
||||||
data = appObject.files[uri.substring(1)];
|
data = appObject.files[uri.substring(1)];
|
||||||
data = await getBlobOrContent(data);
|
data = await getBlobOrContent(data);
|
||||||
headers = {
|
headers = {
|
||||||
@ -767,10 +769,10 @@ ssb.addEventListener('connections', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
async function loadSettings() {
|
async function loadSettings() {
|
||||||
var data;
|
let data;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var settings = new Database('core').get('settings');
|
let settings = new Database('core').get('settings');
|
||||||
if (settings) {
|
if (settings) {
|
||||||
data = JSON.parse(settings);
|
data = JSON.parse(settings);
|
||||||
}
|
}
|
||||||
@ -816,7 +818,7 @@ function enableStats(process, enabled) {
|
|||||||
loadSettings().then(function() {
|
loadSettings().then(function() {
|
||||||
httpd.all("/login", auth.handler);
|
httpd.all("/login", auth.handler);
|
||||||
httpd.all("", function(request, response) {
|
httpd.all("", function(request, response) {
|
||||||
var match;
|
let match;
|
||||||
if (request.uri === "/" || request.uri === "") {
|
if (request.uri === "/" || request.uri === "") {
|
||||||
response.writeHead(303, {"Location": (request.client.tls ? 'https://' : 'http://') + request.headers.host + gGlobalSettings.index, "Content-Length": "0"});
|
response.writeHead(303, {"Location": (request.client.tls ? 'https://' : 'http://') + request.headers.host + gGlobalSettings.index, "Content-Length": "0"});
|
||||||
return response.end();
|
return response.end();
|
||||||
@ -837,15 +839,15 @@ loadSettings().then(function() {
|
|||||||
} else if (match = /^(.*)(\/(?:save|delete)?)$/.exec(request.uri)) {
|
} else if (match = /^(.*)(\/(?:save|delete)?)$/.exec(request.uri)) {
|
||||||
return blobHandler(request, response, match[1], match[2]);
|
return blobHandler(request, response, match[1], match[2]);
|
||||||
} else if (match = /^\/trace$/.exec(request.uri)) {
|
} else if (match = /^\/trace$/.exec(request.uri)) {
|
||||||
var data = trace();
|
let data = trace();
|
||||||
response.writeHead(200, {"Content-Type": "application/json; charset=utf-8", "Content-Length": data.length.toString()});
|
response.writeHead(200, {"Content-Type": "application/json; charset=utf-8", "Content-Length": data.length.toString()});
|
||||||
return response.end(data);
|
return response.end(data);
|
||||||
} else if (match = /^\/disconnections$/.exec(request.uri)) {
|
} else if (match = /^\/disconnections$/.exec(request.uri)) {
|
||||||
var data = utf8Encode(JSON.stringify(disconnectionsDebug(), null, 2));
|
let data = utf8Encode(JSON.stringify(disconnectionsDebug(), null, 2));
|
||||||
response.writeHead(200, {"Content-Type": "application/json; charset=utf-8", "Content-Length": data.byteLength.toString()});
|
response.writeHead(200, {"Content-Type": "application/json; charset=utf-8", "Content-Length": data.byteLength.toString()});
|
||||||
return response.end(data);
|
return response.end(data);
|
||||||
} else if (match = /^\/debug$/.exec(request.uri)) {
|
} else if (match = /^\/debug$/.exec(request.uri)) {
|
||||||
var data = JSON.stringify(getDebug(), null, 2);
|
let data = JSON.stringify(getDebug(), null, 2);
|
||||||
response.writeHead(200, {"Content-Type": "application/json; charset=utf-8", "Content-Length": data.length.toString()});
|
response.writeHead(200, {"Content-Type": "application/json; charset=utf-8", "Content-Length": data.length.toString()});
|
||||||
return response.end(data);
|
return response.end(data);
|
||||||
} else if (request.uri == "/robots.txt") {
|
} else if (request.uri == "/robots.txt") {
|
||||||
@ -853,7 +855,7 @@ loadSettings().then(function() {
|
|||||||
} else if ((match = /^\/.well-known\/(.*)/.exec(request.uri)) && request.uri.indexOf("..") == -1) {
|
} else if ((match = /^\/.well-known\/(.*)/.exec(request.uri)) && request.uri.indexOf("..") == -1) {
|
||||||
return wellKnownHandler(request, response, match[1]);
|
return wellKnownHandler(request, response, match[1]);
|
||||||
} else {
|
} else {
|
||||||
var data = "File not found.";
|
let data = "File not found.";
|
||||||
response.writeHead(404, {"Content-Type": "text/plain; charset=utf-8", "Content-Length": data.length.toString()});
|
response.writeHead(404, {"Content-Type": "text/plain; charset=utf-8", "Content-Length": data.length.toString()});
|
||||||
return response.end(data);
|
return response.end(data);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import * as core from './core.js';
|
import * as core from './core.js';
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
let gHandlers = [];
|
let gHandlers = [];
|
||||||
let gSocketHandlers = [];
|
let gSocketHandlers = [];
|
||||||
let gBadRequests = {};
|
let gBadRequests = {};
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
<span>😎</span>
|
<span>😎</span>
|
||||||
<a accesskey="h" data-tip="Open home app." href="/" style="color: #fff">Tilde Friends</a>
|
<a accesskey="h" data-tip="Open home app." href="/" style="color: #fff">Tilde Friends</a>
|
||||||
<a accesskey="a" data-tip="Open apps list." href="/~core/apps/">apps</a>
|
<a accesskey="a" data-tip="Open apps list." href="/~core/apps/">apps</a>
|
||||||
<a accesskey="e" data-tip="Toggle the app editor." href="#" onclick="event.preventDefault(); toggleEdit()">edit</a>
|
<a accesskey="e" data-tip="Toggle the app editor." href="#" id="edit_link">edit</a>
|
||||||
<a accesskey="p" data-tip="View and change permissions." href="#" onclick="showPermissions()">🎛️</a>
|
<a accesskey="p" data-tip="View and change permissions." href="#" id="show_permissions_link">🎛️</a>
|
||||||
<span id="status"></span>
|
<span id="status"></span>
|
||||||
<span id="requests"></span>
|
<span id="requests"></span>
|
||||||
<span id="permissions_settings"></span>
|
<span id="permissions_settings"></span>
|
||||||
@ -22,31 +22,31 @@
|
|||||||
<div id="content" class="hbox" style="flex: 1 1; width: 100%">
|
<div id="content" class="hbox" style="flex: 1 1; width: 100%">
|
||||||
<div id="statsPane" class="vbox" style="display: none; flex 1 1">
|
<div id="statsPane" class="vbox" style="display: none; flex 1 1">
|
||||||
<div class="hbox">
|
<div class="hbox">
|
||||||
<input type="button" id="closeStats" name="closeStats" value="Close" onclick="closeStats()">
|
<input type="button" id="closeStats" name="closeStats" value="Close">
|
||||||
</div>
|
</div>
|
||||||
<div id="graphs" class="vbox" style="height: 100%"></div>
|
<div id="graphs" class="vbox" style="height: 100%"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="editPane" class="vbox" style="display: none">
|
<div id="editPane" class="vbox" style="display: none">
|
||||||
<div class="navigation hbox">
|
<div class="navigation hbox">
|
||||||
<input type="button" id="closeEditor" name="closeEditor" value="Close" onclick="closeEditor()">
|
<input type="button" id="closeEditor" name="closeEditor" value="Close">
|
||||||
<input type="button" id="save" name="save" value="Save" onclick="save()">
|
<input type="button" id="save" name="save" value="Save">
|
||||||
<input type="text" id="name" name="name" style="flex: 1 1; min-width: 1em"></input>
|
<input type="text" id="name" name="name" style="flex: 1 1; min-width: 1em"></input>
|
||||||
<input type="button" id="delete" name="delete" value="Delete" onclick="deleteApp()">
|
<input type="button" id="delete" name="delete" value="Delete">
|
||||||
<input type="button" onclick="event.preventDefault(); trace()" value="Trace">
|
<input type="button" id="trace_button" value="Trace">
|
||||||
<input type="button" onclick="event.preventDefault(); toggleStats()" value="Stats">
|
<input type="button" id="stats_button" value="Stats">
|
||||||
</div>
|
</div>
|
||||||
<div class="hbox" style="height: 100%">
|
<div class="hbox" style="height: 100%">
|
||||||
<div id="filesPane">
|
<div id="filesPane">
|
||||||
<div class="hbox">
|
<div class="hbox">
|
||||||
<span id="files_header">Files</span>
|
<span id="files_header">Files</span>
|
||||||
<span id="files_hide" onclick="hideFiles()">«</span>
|
<span id="files_hide">«</span>
|
||||||
<span id="files_show" onclick="showFiles()">»</span>
|
<span id="files_show">»</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="files_content">
|
<div id="files_content">
|
||||||
<ul id="files"></ul>
|
<ul id="files"></ul>
|
||||||
<br>
|
<br>
|
||||||
<div><button onclick="newFile()">New File</button></div>
|
<div><button id="new_file_button">New File</button></div>
|
||||||
<div><button onclick="removeFile()">Remove File</button></div>
|
<div><button id="remove_file_button">Remove File</button></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="docPane" style="display: flex; flex: 1 1 50%; flex-flow: column">
|
<div id="docPane" style="display: flex; flex: 1 1 50%; flex-flow: column">
|
||||||
@ -62,6 +62,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<script src="/split/split.min.js"></script>
|
<script src="/split/split.min.js"></script>
|
||||||
<script src="/smoothie/smoothie.js"></script>
|
<script src="/smoothie/smoothie.js"></script>
|
||||||
<script src="/static/client.js"></script>
|
<script src="/static/client.js" type="module"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
Reference in New Issue
Block a user