WIP
parent
e3ac9edfe4
commit
4cce6bab09
@ -0,0 +1,85 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const Promise = require("bluebird");
|
||||||
|
const defaultValue = require("default-value");
|
||||||
|
|
||||||
|
const errors = require("../../../errors");
|
||||||
|
const validate = require("../../../middlewares/validate-payload");
|
||||||
|
const processDeviceID = require("../../../process-device-id");
|
||||||
|
|
||||||
|
module.exports = function({ db, knex, configuration, fullyQualifyUser }) {
|
||||||
|
let router = require("express-promise-router")();
|
||||||
|
|
||||||
|
function validateRegisterPayload(payload) {
|
||||||
|
let {assertProperties, isPresent, isString, isOneOf, isBoolean} = require("../../../validator-lib");
|
||||||
|
|
||||||
|
assertProperties(payload, {
|
||||||
|
kind: [ isOneOf("user", "guest") ],
|
||||||
|
device_id: [ isString ],
|
||||||
|
initial_device_display_name: [ isString ],
|
||||||
|
username: [ isPresent, isString, (username) => {
|
||||||
|
if (!/^[a-z0-9._=/-]+$/.test(username)) {
|
||||||
|
throw new errors.InvalidUsername("Usernames may only contain a-z, 0-9, and . _ = - /");
|
||||||
|
} else if (username.startsWith("_")) {
|
||||||
|
throw new errors.ExclusiveResource("Usernames starting with _ are reserved for bridges");
|
||||||
|
}
|
||||||
|
} ],
|
||||||
|
password: [ isPresent, isString ], /* FIXME: Password strength */
|
||||||
|
inhibit_login: [ isBoolean ],
|
||||||
|
bind_email: [ isBoolean ]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
router.post("/r0/register", validate(validateRegisterPayload), (req, res) => {
|
||||||
|
// https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-register
|
||||||
|
// Register for an account on this homeserver. This API endpoint uses the User-Interactive Authentication API.
|
||||||
|
|
||||||
|
/* FIXME: Support User-Interactive Authentication (eg. for registration CAPTCHAs) */
|
||||||
|
/* FIXME: Rate-limit */
|
||||||
|
|
||||||
|
if (req.body.kind === "guest") {
|
||||||
|
/* TODO: Re-evaluate this, once it becomes clearer how to deal with guest users and peeking across federation (ref. https://github.com/matrix-org/matrix-doc/pull/1777) */
|
||||||
|
throw new errors.Forbidden("Guest registrations are disabled on this server");
|
||||||
|
} else {
|
||||||
|
let inhibitLogin = defaultValue(req.body.inhibit_login, false);
|
||||||
|
/* FILEBUG: Default for bind_email is not clearly specified in spec */
|
||||||
|
/* FIXME: Actually implement e-mail binding on identity server */
|
||||||
|
let bindEmail = defaultValue(req.body.bind_email, false);
|
||||||
|
let deviceId = processDeviceID(req.body.deviceID);
|
||||||
|
|
||||||
|
return knex.transaction((transaction) => {
|
||||||
|
return Promise.try(() => {
|
||||||
|
return db.users.create({
|
||||||
|
type: "user",
|
||||||
|
username: req.body.username,
|
||||||
|
password: req.body.password
|
||||||
|
}, transaction);
|
||||||
|
}).then((user) => {
|
||||||
|
return Promise.try(() => {
|
||||||
|
if (!inhibitLogin) {
|
||||||
|
return db.devices.createDeviceSession({
|
||||||
|
name: req.body.initial_device_display_name,
|
||||||
|
deviceId: deviceId,
|
||||||
|
userId: user.id
|
||||||
|
}, transaction);
|
||||||
|
}
|
||||||
|
}).then((device) => {
|
||||||
|
let sessionDetails = (device != null)
|
||||||
|
? { access_token: device.token, device_id: device.device_id }
|
||||||
|
: {};
|
||||||
|
|
||||||
|
res.send({
|
||||||
|
user_id: fullyQualifyUser(user.username),
|
||||||
|
home_server: configuration.hostname,
|
||||||
|
...sessionDetails
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}).catch({ name: "UniqueConstraintViolationError", table: "users", column: "username" }, (_error) => {
|
||||||
|
throw new errors.UserExists("That username is already taken");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return router;
|
||||||
|
}
|
Loading…
Reference in New Issue