WIP
parent
2aa7be6e9a
commit
82af54b214
@ -0,0 +1,78 @@
|
|||||||
|
module.exports = {
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"commonjs": true,
|
||||||
|
"es6": true,
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaFeatures": {
|
||||||
|
"experimentalObjectRestSpread": true,
|
||||||
|
"jsx": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
"react"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
/* Things that should effectively be syntax errors. */
|
||||||
|
"indent": [ "error", "tab", {
|
||||||
|
SwitchCase: 1
|
||||||
|
}],
|
||||||
|
"linebreak-style": [ "error", "unix" ],
|
||||||
|
"semi": [ "error", "always" ],
|
||||||
|
/* Things that are always mistakes. */
|
||||||
|
"getter-return": [ "error" ],
|
||||||
|
"no-compare-neg-zero": [ "error" ],
|
||||||
|
"no-dupe-args": [ "error" ],
|
||||||
|
"no-dupe-keys": [ "error" ],
|
||||||
|
"no-duplicate-case": [ "error" ],
|
||||||
|
"no-empty": [ "error" ],
|
||||||
|
"no-empty-character-class": [ "error" ],
|
||||||
|
"no-ex-assign": [ "error" ],
|
||||||
|
"no-extra-semi": [ "error" ],
|
||||||
|
"no-func-assign": [ "error" ],
|
||||||
|
"no-invalid-regexp": [ "error" ],
|
||||||
|
"no-irregular-whitespace": [ "error" ],
|
||||||
|
"no-obj-calls": [ "error" ],
|
||||||
|
"no-sparse-arrays": [ "error" ],
|
||||||
|
"no-undef": [ "error" ],
|
||||||
|
"no-unreachable": [ "error" ],
|
||||||
|
"no-unsafe-finally": [ "error" ],
|
||||||
|
"use-isnan": [ "error" ],
|
||||||
|
"valid-typeof": [ "error" ],
|
||||||
|
"curly": [ "error" ],
|
||||||
|
"no-caller": [ "error" ],
|
||||||
|
"no-fallthrough": [ "error" ],
|
||||||
|
"no-extra-bind": [ "error" ],
|
||||||
|
"no-extra-label": [ "error" ],
|
||||||
|
"array-callback-return": [ "error" ],
|
||||||
|
"prefer-promise-reject-errors": [ "error" ],
|
||||||
|
"no-with": [ "error" ],
|
||||||
|
"no-useless-concat": [ "error" ],
|
||||||
|
"no-unused-labels": [ "error" ],
|
||||||
|
"no-unused-expressions": [ "error" ],
|
||||||
|
"no-unused-vars": [ "error" , { argsIgnorePattern: "^_" } ],
|
||||||
|
"no-return-assign": [ "error" ],
|
||||||
|
"no-self-assign": [ "error" ],
|
||||||
|
"no-new-wrappers": [ "error" ],
|
||||||
|
"no-redeclare": [ "error" ],
|
||||||
|
"no-loop-func": [ "error" ],
|
||||||
|
"no-implicit-globals": [ "error" ],
|
||||||
|
"strict": [ "error", "global" ],
|
||||||
|
/* Make JSX not cause 'unused variable' errors. */
|
||||||
|
"react/jsx-uses-react": ["error"],
|
||||||
|
"react/jsx-uses-vars": ["error"],
|
||||||
|
/* Development code that should be removed before deployment. */
|
||||||
|
"no-console": [ "warn" ],
|
||||||
|
"no-constant-condition": [ "warn" ],
|
||||||
|
"no-debugger": [ "warn" ],
|
||||||
|
"no-alert": [ "warn" ],
|
||||||
|
"no-warning-comments": ["warn", {
|
||||||
|
terms: ["fixme"]
|
||||||
|
}],
|
||||||
|
/* Common mistakes that can *occasionally* be intentional. */
|
||||||
|
"no-template-curly-in-string": ["warn"],
|
||||||
|
"no-unsafe-negation": [ "warn" ],
|
||||||
|
}
|
||||||
|
};
|
@ -1 +1,2 @@
|
|||||||
node_modules
|
node_modules
|
||||||
|
config.json
|
@ -0,0 +1,19 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const url = require("url");
|
||||||
|
|
||||||
|
const config = require("./config.json");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
client: "pg",
|
||||||
|
connection: {
|
||||||
|
connectionString: url.format({
|
||||||
|
protocol: "socket",
|
||||||
|
slashes: false,
|
||||||
|
pathname: config.database.socket,
|
||||||
|
query: {
|
||||||
|
db: config.database.database
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,7 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
module.exports = function ({db}) {
|
||||||
|
return {
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
@ -0,0 +1,21 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const util = require("util");
|
||||||
|
const chalk = require("chalk");
|
||||||
|
|
||||||
|
module.exports = function createDebugMiddleware() {
|
||||||
|
return function (req, res, next) {
|
||||||
|
console.log(`## ${chalk.cyan(req.method)} ${chalk.bold.yellow(req.url)}`);
|
||||||
|
|
||||||
|
console.log(util.inspect({
|
||||||
|
query: req.query,
|
||||||
|
params: req.params,
|
||||||
|
host: req.hostname,
|
||||||
|
headers: req.headers,
|
||||||
|
cookies: req.cookies,
|
||||||
|
body: req.body
|
||||||
|
}, {colors: true, depth: null}));
|
||||||
|
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,71 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const errorChain = require("error-chain");
|
||||||
|
|
||||||
|
let HttpError = errorChain("HttpError", { isHttpError: true });
|
||||||
|
|
||||||
|
/*** HTTP 400: Bad Request ***/
|
||||||
|
|
||||||
|
let BadRequest = HttpError.extend("BadRequest", { statusCode: 400, errorCode: "M_UNRECOGNIZED" });
|
||||||
|
let NotJson = BadRequest.extend("NotJson", { errorCode: "M_NOT_JSON" });
|
||||||
|
let BadJson = BadRequest.extend("BadJson", { errorCode: "M_BAD_JSON" });
|
||||||
|
|
||||||
|
/*** HTTP 401: Unauthorized ***/
|
||||||
|
|
||||||
|
let Unauthorized = HttpError.extend("Unauthorized", { statusCode: 401, errorCode: "M_UNAUTHORIZED" });
|
||||||
|
let MissingAccessToken = Unauthorized.extend("MissingAccessToken", { errorCode: "M_MISSING_TOKEN" });
|
||||||
|
let MissingCaptcha = Unauthorized.extend("MissingCaptcha", { errorCode: "M_CAPTCHA_NEEDED" });
|
||||||
|
|
||||||
|
/*** HTTP 403: Forbidden ***/
|
||||||
|
|
||||||
|
let Forbidden = HttpError.extend("Forbidden", { statusCode: 403, errorCode: "M_FORBIDDEN" });
|
||||||
|
let InvalidAccessToken = Forbidden.extend("InvalidAccessToken", { errorCode: "M_UNKNOWN_TOKEN" });
|
||||||
|
let InvalidCaptcha = Forbidden.extend("InvalidCaptcha", { errorCode: "M_CAPTCHA_INVALID" });
|
||||||
|
let ServerNotTrusted = Forbidden.extend("ServerNotTrusted", { errorCode: "M_SERVER_NOT_TRUSTED" });
|
||||||
|
let NoGuestAccess = Forbidden.extend("NoGuestAccess", { errorCode: "M_GUEST_ACCESS_FORBIDDEN" });
|
||||||
|
let ExternalIdentifierAuthenticationFailed = Forbidden.extend("ExternalIdentifierAuthenticationFailed", { errorCode: "M_THREEPID_AUTH_FAILED" });
|
||||||
|
|
||||||
|
/*** HTTP 404: Not Found ***/
|
||||||
|
|
||||||
|
let NotFound = HttpError.extend("NotFound", { statusCode: 404, errorCode: "M_NOT_FOUND" });
|
||||||
|
let ExternalIdentifierNotFound = NotFound.extend("ExternalIdentifierNotFound", { errorCode: "M_THREEPID_NOT_FOUND" });
|
||||||
|
|
||||||
|
/*** HTTP 409: Conflict ***/
|
||||||
|
|
||||||
|
let ResourceExists = HttpError.extend("ResourceExists", { statusCode: 409 });
|
||||||
|
let UserExists = ResourceExists.extend("UserExists", { errorCode: "M_USER_IN_USE" });
|
||||||
|
let RoomExists = ResourceExists.extend("RoomExists", { errorCode: "M_ROOM_IN_USE" });
|
||||||
|
let ExternalIdentifierExists = ResourceExists.extend("ExternalIdentifierExists", { errorCode: "M_THREEPID_IN_USE" });
|
||||||
|
|
||||||
|
/*** HTTP 413: Payload Too Large ***/
|
||||||
|
|
||||||
|
let RequestTooLarge = HttpError.extend("RequestTooLarge", { statusCode: 413, errorCode: "M_TOO_LARGE" });
|
||||||
|
|
||||||
|
/*** HTTP 422: Unprocessable Entity (Invalid Payload) ***/
|
||||||
|
|
||||||
|
let InvalidData = HttpError.extend("InvalidData", { statusCode: 422 });
|
||||||
|
let InvalidUsername = InvalidData.extend("InvalidUsername", { errorCode: "M_INVALID_USERNAME" });
|
||||||
|
let InvalidRoomVersion = InvalidData.extend("InvalidRoomVersion", { errorCode: "M_UNSUPPORTED_ROOM_VERSION" });
|
||||||
|
let InvalidRoomState = InvalidData.extend("InvalidRoomState", { errorCode: "M_INVALID_ROOM_STATE" });
|
||||||
|
let InvalidStateChange = InvalidData.extend("InvalidStateChange", { errorCode: "M_BAD_STATE" });
|
||||||
|
let InvalidExternalIdentifier = InvalidData.extend("InvalidExternalIdentifier", { errorCode: "M_THREEPID_DENIED" });
|
||||||
|
let InvalidParameter = InvalidData.extend("InvalidParameter", { errorCode: "M_INVALID_PARAM" });
|
||||||
|
let MissingParameter = InvalidData.extend("MissingParameter", { errorCode: "M_MISSING_PARAM" });
|
||||||
|
let IncompatibleRoomVersion = InvalidData.extend("IncompatibleRoomVersion", { errorCode: "M_INCOMPATIBLE_ROOM_VERSION" });
|
||||||
|
|
||||||
|
/*** HTTP 429: Too Many Requests ***/
|
||||||
|
|
||||||
|
let TooManyRequests = HttpError.extend("TooManyRequests", { statusCode: 429, errorCode: "M_LIMIT_EXCEEDED" });
|
||||||
|
|
||||||
|
/*** HTTP 500: Internal Server Error ***/
|
||||||
|
|
||||||
|
let InternalServerError = HttpError.extend("InternalServerError", { statusCode: 500 });
|
||||||
|
let UnknownError = InternalServerError.extend("UnknownError", { errorCode: "M_UNKNOWN" });
|
||||||
|
|
||||||
|
/*** HTTP 503: Service Unavailable ***/
|
||||||
|
|
||||||
|
let ExclusiveResource = HttpError.extend("ExclusiveResource", { statusCode: 503, errorCode: "M_EXCLUSIVE" });
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
HttpError, Unauthorized, MissingAccessToken, InvalidAccessToken, NotJson, BadJson, NotFound, TooManyRequests, MissingCaptcha, InvalidCaptcha, ServerNotTrusted, NoGuestAccess, UserExists, RoomExists, RequestTooLarge, InvalidUsername, InvalidRoomVersion, InvalidRoomState, InvalidStateChange, InvalidParameter, MissingParameter, IncompatibleRoomVersion, InternalServerError, UnknownError, ExclusiveResource, ResourceExists, Forbidden, BadRequest, ExternalIdentifierNotFound, ExternalIdentifierExists, ExternalIdentifierAuthenticationFailed, InvalidExternalIdentifier
|
||||||
|
};
|
@ -0,0 +1,8 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const defaultValue = require("default-value");
|
||||||
|
|
||||||
|
module.exports = function (req, _res, next) {
|
||||||
|
req.matrixAccessToken = defaultValue(req.query.access_token, req.headers.Authorization);
|
||||||
|
next();
|
||||||
|
};
|
@ -0,0 +1,28 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const defaultValue = require("default-value");
|
||||||
|
const http = require("http");
|
||||||
|
|
||||||
|
module.exports = function errorHandler(error, _req, res, _next) {
|
||||||
|
let statusCode = (error.isHttpError && error.statusCode != null)
|
||||||
|
? error.statusCode
|
||||||
|
: 500;
|
||||||
|
|
||||||
|
let errorCode = (error.isHttpError && error.errorCode != null)
|
||||||
|
? error.errorCode
|
||||||
|
: "M_UNKNOWN";
|
||||||
|
|
||||||
|
let errorMessage = (error.errorCode !== 500)
|
||||||
|
? defaultValue(error.message, http.STATUS_CODES[statusCode])
|
||||||
|
: "An internal server error occurred. Please contact the server administrator for more information."
|
||||||
|
/* TODO: Add contact details? */
|
||||||
|
|
||||||
|
let errorMeta = (error.errorMeta != null)
|
||||||
|
? error.errorMeta
|
||||||
|
: {};
|
||||||
|
|
||||||
|
res.json(Object.assign({}, errorMeta, {
|
||||||
|
errcode: errorCode,
|
||||||
|
error: errorMessage
|
||||||
|
}));
|
||||||
|
};
|
@ -0,0 +1,11 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const errors = require("../errors");
|
||||||
|
|
||||||
|
module.exports = function requireAccessToken(req, res, next) {
|
||||||
|
if (req.matrixAccessToken == null) {
|
||||||
|
throw new errors.UnauthorizedError("An access token is required, but none was provided", {
|
||||||
|
errorCode: "M_MISSING_TOKEN"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,16 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
module.exports = function(state) {
|
||||||
|
let router = require("express-promise-router")();
|
||||||
|
|
||||||
|
router.get("/versions", (req, res) => {
|
||||||
|
/* TODO: Support more specification versions? */
|
||||||
|
res.json({
|
||||||
|
versions: [
|
||||||
|
"r0.4.0"
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return router;
|
||||||
|
}
|
Loading…
Reference in New Issue