mirror of
https://github.com/turt2live/matrix-dimension.git
synced 2024-09-29 20:25:58 +00:00
parent
f031a7833a
commit
afeb2c7bfe
34
migrations/20170527035704-add-tokens-table.js
Normal file
34
migrations/20170527035704-add-tokens-table.js
Normal file
@ -0,0 +1,34 @@
|
||||
'use strict';
|
||||
|
||||
var dbm;
|
||||
var type;
|
||||
var seed;
|
||||
|
||||
/**
|
||||
* We receive the dbmigrate dependency from dbmigrate initially.
|
||||
* This enables us to not have to rely on NODE_PATH.
|
||||
*/
|
||||
exports.setup = function (options, seedLink) {
|
||||
dbm = options.dbmigrate;
|
||||
type = dbm.dataType;
|
||||
seed = seedLink;
|
||||
};
|
||||
|
||||
exports.up = function (db) {
|
||||
return db.createTable("tokens", {
|
||||
id: {type: 'int', primaryKey: true, autoIncrement: true, notNull: true},
|
||||
matrixUserId: {type: 'string', notNull: true},
|
||||
matrixServerName: {type: 'string', notNull: true},
|
||||
matrixAccessToken: {type: 'string', notNull: true},
|
||||
scalarToken: {type: 'string', notNull: true},
|
||||
expires: {type: 'timestamp', notNull: true}
|
||||
});
|
||||
};
|
||||
|
||||
exports.down = function (db) {
|
||||
return db.dropTable("tokens");
|
||||
};
|
||||
|
||||
exports._meta = {
|
||||
"version": 1
|
||||
};
|
@ -5,7 +5,7 @@
|
||||
"main": "app.js",
|
||||
"license": "GPL-3.0",
|
||||
"scripts": {
|
||||
"dev": "webpack-dev-server --inline --progress --port 8080",
|
||||
"dev": "webpack-dev-server --inline --progress --port 8080 --host 0.0.0.0",
|
||||
"build": "rimraf web-dist && webpack --progress --profile --bail"
|
||||
},
|
||||
"repository": {
|
||||
@ -14,6 +14,7 @@
|
||||
},
|
||||
"author": "Travis Ralston",
|
||||
"dependencies": {
|
||||
"body-parser": "^1.17.2",
|
||||
"chalk": "^1.1.3",
|
||||
"config": "^1.25.1",
|
||||
"db-migrate": "^0.10.0-beta.20",
|
||||
@ -21,6 +22,8 @@
|
||||
"express": "^4.15.2",
|
||||
"js-yaml": "^3.8.2",
|
||||
"moment": "^2.18.1",
|
||||
"random-string": "^0.2.0",
|
||||
"request": "^2.81.0",
|
||||
"sequelize": "^3.30.4",
|
||||
"sqlite3": "^3.1.8",
|
||||
"winston": "^2.3.1"
|
||||
|
@ -2,6 +2,10 @@ var express = require("express");
|
||||
var config = require("config");
|
||||
var log = require("./util/LogService");
|
||||
var DimensionStore = require("./storage/DimensionStore");
|
||||
var bodyParser = require('body-parser');
|
||||
var path = require("path");
|
||||
var MatrixLiteClient = require("./matrix/MatrixLiteClient");
|
||||
var randomString = require("random-string");
|
||||
|
||||
/**
|
||||
* Primary entry point for Dimension
|
||||
@ -16,6 +20,27 @@ class Dimension {
|
||||
this._db = db;
|
||||
this._app = express();
|
||||
this._app.use(express.static('web-dist'));
|
||||
this._app.use(bodyParser.json());
|
||||
|
||||
// Register routes for angular app
|
||||
this._app.get(['/riot/*', '/app/*', '/splash/*'], (req, res) => {
|
||||
res.sendFile(path.join(__dirname, "..", "web-dist", "index.html"));
|
||||
});
|
||||
|
||||
// Allow CORS
|
||||
this._app.use((req, res, next) => {
|
||||
res.setHeader("Access-Control-Allow-Origin", "*");
|
||||
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
|
||||
next();
|
||||
});
|
||||
|
||||
// Logging incoming requests
|
||||
this._app.use((req, res, next) => {
|
||||
log.verbose("Dimension", "Incoming: " + req.method + " " + req.url);
|
||||
next();
|
||||
});
|
||||
|
||||
this._app.post("/api/v1/scalar/register", this._scalarRegister.bind(this));
|
||||
}
|
||||
|
||||
start() {
|
||||
@ -23,6 +48,25 @@ class Dimension {
|
||||
log.info("Dimension", "API and UI listening on " + config.get("web.address") + ":" + config.get("web.port"));
|
||||
}
|
||||
|
||||
_scalarRegister(req, res) {
|
||||
var tokenInfo = req.body;
|
||||
if (!tokenInfo || !tokenInfo['access_token'] || !tokenInfo['token_type'] || !tokenInfo['matrix_server_name'] || !tokenInfo['expires_in']) {
|
||||
res.status(400).send('Missing OpenID');
|
||||
return;
|
||||
}
|
||||
|
||||
var client = new MatrixLiteClient(tokenInfo);
|
||||
var scalarToken = randomString({length: 25});
|
||||
client.getSelfMxid().then(mxid => {
|
||||
return this._db.createToken(mxid, tokenInfo, scalarToken);
|
||||
}).then(() => {
|
||||
res.setHeader("Content-Type", "application/json");
|
||||
res.send(JSON.stringify({scalar_token: scalarToken}));
|
||||
}, err => {
|
||||
throw err;
|
||||
//res.status(500).send(err.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Dimension;
|
11
src/OpenID.js
Normal file
11
src/OpenID.js
Normal file
@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Serves the purpose of being a documentation endpoint
|
||||
*/
|
||||
class OpenID {
|
||||
access_token = "";
|
||||
token_type = "";
|
||||
matrix_server_name = "";
|
||||
expires_in = 0;
|
||||
}
|
||||
|
||||
module.exports = OpenID;
|
53
src/matrix/MatrixLiteClient.js
Normal file
53
src/matrix/MatrixLiteClient.js
Normal file
@ -0,0 +1,53 @@
|
||||
var request = require('request');
|
||||
var log = require("../util/LogService");
|
||||
|
||||
/**
|
||||
* Represents a lightweight matrix client with minimal functionality
|
||||
*/
|
||||
class MatrixLiteClient {
|
||||
|
||||
/**
|
||||
* Creates a new matrix client
|
||||
* @param {OpenID} openId the open ID to use
|
||||
*/
|
||||
constructor(openId) {
|
||||
this._openId = openId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Matrix User ID that owns this open ID
|
||||
* @return {Promise<string>} resolves to the mxid
|
||||
*/
|
||||
getSelfMxid() {
|
||||
return this._do("GET", "/_matrix/federation/v1/openid/userinfo").then((response, body) => {
|
||||
var json = JSON.parse(response.body);
|
||||
return json['sub'];
|
||||
});
|
||||
}
|
||||
|
||||
_do(method, endpoint, qs = null, body = null) {
|
||||
var url = "http://" + this._openId.matrix_server_name + endpoint;
|
||||
|
||||
log.verbose("MatrixLiteClient", "Performing request: " + url);
|
||||
|
||||
if (!qs) qs = {};
|
||||
qs['access_token'] = this._openId.access_token;
|
||||
|
||||
var params = {
|
||||
url: url,
|
||||
method: method,
|
||||
form: body,
|
||||
qs: qs
|
||||
};
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
request(params, (err, response, body) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else resolve(response, body);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MatrixLiteClient;
|
@ -2,6 +2,7 @@ var DBMigrate = require("db-migrate");
|
||||
var log = require("./../util/LogService");
|
||||
var Sequelize = require('sequelize');
|
||||
var dbConfig = require("../../config/database.json");
|
||||
var moment = require("moment");
|
||||
|
||||
/**
|
||||
* Primary storage for Dimension.
|
||||
@ -54,9 +55,40 @@ class DimensionStore {
|
||||
|
||||
_bindModels() {
|
||||
// Models
|
||||
this.__Tokens = this._orm.import(__dirname + "/models/tokens");
|
||||
|
||||
// Relationships
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Scalar token
|
||||
* @param {string} mxid the matrix user id
|
||||
* @param {OpenID} openId the open ID
|
||||
* @param {string} scalarToken the token associated with the user
|
||||
* @returns {Promise<>} resolves when complete
|
||||
*/
|
||||
createToken(mxid, openId, scalarToken) {
|
||||
return this.__Tokens.create({
|
||||
matrixUserId: mxid,
|
||||
matrixServerName: openId.matrix_server_name,
|
||||
matrixAccessToken: openId.access_token,
|
||||
scalarToken: scalarToken,
|
||||
expires: moment().add(openId.expires_in, 'seconds').toDate()
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to determine if a token is valid or not
|
||||
* @param {string} scalarToken the scalar token to check
|
||||
* @returns {Promise<>} resolves if valid, rejected otherwise
|
||||
*/
|
||||
checkToken(scalarToken) {
|
||||
return this.__Tokens.find({where: {scalarToken: scalarToken}}).then(token => {
|
||||
if (!token) return Promise.reject();
|
||||
//if (moment().isAfter(moment(token.expires))) return this.__Tokens.destroy({where: {id: token.id}}).then(() => Promise.reject());
|
||||
return Promise.resolve();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = DimensionStore;
|
40
src/storage/models/tokens.js
Normal file
40
src/storage/models/tokens.js
Normal file
@ -0,0 +1,40 @@
|
||||
module.exports = function (sequelize, DataTypes) {
|
||||
return sequelize.define('tokens', {
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
field: 'id'
|
||||
},
|
||||
matrixUserId: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
field: 'matrixUserId'
|
||||
},
|
||||
matrixServerName: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
field: 'matrixServerName'
|
||||
},
|
||||
matrixAccessToken: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
field: 'matrixAccessToken'
|
||||
},
|
||||
scalarToken: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
field: 'scalarToken'
|
||||
},
|
||||
expires: {
|
||||
type: DataTypes.TIME,
|
||||
allowNull: false,
|
||||
field: 'expires'
|
||||
}
|
||||
}, {
|
||||
tableName: 'tokens',
|
||||
underscored: false,
|
||||
timestamps: false
|
||||
});
|
||||
};
|
@ -69,7 +69,7 @@ var log = new winston.Logger({
|
||||
});
|
||||
|
||||
function doLog(level, module, messageOrObject) {
|
||||
if (typeof(messageOrObject) === 'object')
|
||||
if (typeof(messageOrObject) === 'object' && !(messageOrObject instanceof Error))
|
||||
messageOrObject = JSON.stringify(messageOrObject);
|
||||
var message = "[" + module + "] " + messageOrObject;
|
||||
log.log(level, message);
|
||||
|
@ -23,7 +23,7 @@ module.exports = function () {
|
||||
|
||||
config.output = {
|
||||
path: root('web-dist'),
|
||||
publicPath: isProd ? '/' : 'http://localhost:8080',
|
||||
publicPath: isProd ? '/' : '/', //http://0.0.0.0:8080',
|
||||
filename: isProd ? 'js/[name].[hash].js' : 'js/[name].js',
|
||||
chunkFilename: isProd ? '[id].[hash].chunk.js' : '[id].chunk.js'
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user