summaryrefslogtreecommitdiff
path: root/src/api
diff options
context:
space:
mode:
authorTosuke <tasukeprg@gmail.com>2017-01-06 14:39:24 +0900
committerTosuke <tasukeprg@gmail.com>2017-01-06 14:39:24 +0900
commit0420fee5d2c6a944a7b2cf13307dfadce9796b59 (patch)
treed8c361b2c340c03927a5a417e5a91b3ab58db34b /src/api
parent[Swagger]Add /auth/accept (diff)
parentUpdate changelog (diff)
downloadsharkey-0420fee5d2c6a944a7b2cf13307dfadce9796b59.tar.gz
sharkey-0420fee5d2c6a944a7b2cf13307dfadce9796b59.tar.bz2
sharkey-0420fee5d2c6a944a7b2cf13307dfadce9796b59.zip
Merge branch 'master' of github.com:syuilo/misskey into swagger
Diffstat (limited to 'src/api')
-rw-r--r--src/api/authenticate.ts32
-rw-r--r--src/api/common/is-native-token.ts1
-rw-r--r--src/api/endpoints/auth/accept.js35
-rw-r--r--src/api/endpoints/auth/session/userkey.js8
-rw-r--r--src/api/endpoints/users/posts.js22
-rw-r--r--src/api/models/access-token.ts6
-rw-r--r--src/api/models/userkey.ts5
-rw-r--r--src/api/private/signup.ts2
-rw-r--r--src/api/serializers/app.ts4
-rw-r--r--src/api/streaming.ts41
10 files changed, 98 insertions, 58 deletions
diff --git a/src/api/authenticate.ts b/src/api/authenticate.ts
index 5798adb83d..50a55e51b7 100644
--- a/src/api/authenticate.ts
+++ b/src/api/authenticate.ts
@@ -1,7 +1,8 @@
import * as express from 'express';
import App from './models/app';
import User from './models/user';
-import Userkey from './models/userkey';
+import AccessToken from './models/access-token';
+import isNativeToken from './common/is-native-token';
export interface IAuthContext {
/**
@@ -20,10 +21,14 @@ export interface IAuthContext {
isSecure: boolean;
}
-export default (req: express.Request) =>
- new Promise<IAuthContext>(async (resolve, reject) => {
+export default (req: express.Request) => new Promise<IAuthContext>(async (resolve, reject) => {
const token = req.body['i'];
- if (token) {
+
+ if (token == null) {
+ return resolve({ app: null, user: null, isSecure: false });
+ }
+
+ if (isNativeToken(token)) {
const user = await User
.findOne({ token: token });
@@ -36,26 +41,21 @@ export default (req: express.Request) =>
user: user,
isSecure: true
});
- }
-
- const userkey = req.headers['userkey'] || req.body['_userkey'];
- if (userkey) {
- const userkeyDoc = await Userkey.findOne({
- key: userkey
+ } else {
+ const accessToken = await AccessToken.findOne({
+ hash: token
});
- if (userkeyDoc === null) {
- return reject('invalid userkey');
+ if (accessToken === null) {
+ return reject('invalid signature');
}
const app = await App
- .findOne({ _id: userkeyDoc.app_id });
+ .findOne({ _id: accessToken.app_id });
const user = await User
- .findOne({ _id: userkeyDoc.user_id });
+ .findOne({ _id: accessToken.user_id });
return resolve({ app: app, user: user, isSecure: false });
}
-
- return resolve({ app: null, user: null, isSecure: false });
});
diff --git a/src/api/common/is-native-token.ts b/src/api/common/is-native-token.ts
new file mode 100644
index 0000000000..0769a4812e
--- /dev/null
+++ b/src/api/common/is-native-token.ts
@@ -0,0 +1 @@
+export default (token: string) => token[0] == '!';
diff --git a/src/api/endpoints/auth/accept.js b/src/api/endpoints/auth/accept.js
index e584513c05..d60d95aea3 100644
--- a/src/api/endpoints/auth/accept.js
+++ b/src/api/endpoints/auth/accept.js
@@ -4,8 +4,10 @@
* Module dependencies
*/
import rndstr from 'rndstr';
+const crypto = require('crypto');
+import App from '../../models/app';
import AuthSess from '../../models/auth-session';
-import Userkey from '../../models/userkey';
+import AccessToken from '../../models/access-token';
/**
* @swagger
@@ -41,35 +43,46 @@ module.exports = (params, user) =>
new Promise(async (res, rej) =>
{
// Get 'token' parameter
- const token = params.token;
- if (token == null) {
+ const sesstoken = params.token;
+ if (sesstoken == null) {
return rej('token is required');
}
// Fetch token
const session = await AuthSess
- .findOne({ token: token });
+ .findOne({ token: sesstoken });
if (session === null) {
return rej('session not found');
}
- // Generate userkey
- const key = rndstr('a-zA-Z0-9', 32);
+ // Generate access token
+ const token = rndstr('a-zA-Z0-9', 32);
- // Fetch exist userkey
- const exist = await Userkey.findOne({
+ // Fetch exist access token
+ const exist = await AccessToken.findOne({
app_id: session.app_id,
user_id: user._id,
});
if (exist === null) {
- // Insert userkey doc
- await Userkey.insert({
+ // Lookup app
+ const app = await App.findOne({
+ app_id: session.app_id
+ });
+
+ // Generate Hash
+ const sha512 = crypto.createHash('sha512');
+ sha512.update(token + app.secret);
+ const hash = sha512.digest('hex');
+
+ // Insert access token doc
+ await AccessToken.insert({
created_at: new Date(),
app_id: session.app_id,
user_id: user._id,
- key: key
+ token: token,
+ hash: hash
});
}
diff --git a/src/api/endpoints/auth/session/userkey.js b/src/api/endpoints/auth/session/userkey.js
index 73fa643c9c..9252046e57 100644
--- a/src/api/endpoints/auth/session/userkey.js
+++ b/src/api/endpoints/auth/session/userkey.js
@@ -5,7 +5,7 @@
*/
import App from '../../../models/app';
import AuthSess from '../../../models/auth-session';
-import Userkey from '../../../models/userkey';
+import AccessToken from '../../../models/access-token';
import serialize from '../../../serializers/user';
/**
@@ -89,8 +89,8 @@ module.exports = (params) =>
return rej('this session is not allowed yet');
}
- // Lookup userkey
- const userkey = await Userkey.findOne({
+ // Lookup access token
+ const accessToken = await AccessToken.findOne({
app_id: app._id,
user_id: session.user_id
});
@@ -102,7 +102,7 @@ module.exports = (params) =>
// Response
res({
- userkey: userkey.key,
+ access_token: accessToken.token,
user: await serialize(session.user_id, null, {
detail: true
})
diff --git a/src/api/endpoints/users/posts.js b/src/api/endpoints/users/posts.js
index 6d6f8a6904..1b8dfe031b 100644
--- a/src/api/endpoints/users/posts.js
+++ b/src/api/endpoints/users/posts.js
@@ -19,9 +19,19 @@ module.exports = (params, me) =>
new Promise(async (res, rej) =>
{
// Get 'user_id' parameter
- const userId = params.user_id;
- if (userId === undefined || userId === null) {
- return rej('user_id is required');
+ let userId = params.user_id;
+ if (userId === undefined || userId === null || userId === '') {
+ userId = null;
+ }
+
+ // Get 'username' parameter
+ let username = params.username;
+ if (username === undefined || username === null || username === '') {
+ username = null;
+ }
+
+ if (userId === null && username === null) {
+ return rej('user_id or username is required');
}
// Get 'with_replies' parameter
@@ -62,9 +72,9 @@ module.exports = (params, me) =>
}
// Lookup user
- const user = await User.findOne({
- _id: new mongo.ObjectID(userId)
- });
+ const user = userId !== null
+ ? await User.findOne({ _id: new mongo.ObjectID(userId) })
+ : await User.findOne({ username_lower: username.toLowerCase() });
if (user === null) {
return rej('user not found');
diff --git a/src/api/models/access-token.ts b/src/api/models/access-token.ts
new file mode 100644
index 0000000000..f94df954d6
--- /dev/null
+++ b/src/api/models/access-token.ts
@@ -0,0 +1,6 @@
+const collection = global.db.collection('access_tokens');
+
+collection.createIndex('token');
+collection.createIndex('hash');
+
+export default collection;
diff --git a/src/api/models/userkey.ts b/src/api/models/userkey.ts
deleted file mode 100644
index 204f283a28..0000000000
--- a/src/api/models/userkey.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-const collection = global.db.collection('userkeys');
-
-collection.createIndex('key');
-
-export default collection;
diff --git a/src/api/private/signup.ts b/src/api/private/signup.ts
index c50b070052..592dfcceb1 100644
--- a/src/api/private/signup.ts
+++ b/src/api/private/signup.ts
@@ -48,7 +48,7 @@ export default async (req: express.Request, res: express.Response) => {
const hash = bcrypt.hashSync(password, salt);
// Generate secret
- const secret = rndstr('a-zA-Z0-9', 32);
+ const secret = '!' + rndstr('a-zA-Z0-9', 32);
// Create account
const inserted = await User.insert({
diff --git a/src/api/serializers/app.ts b/src/api/serializers/app.ts
index 1c4b244a36..b60bcb97e6 100644
--- a/src/api/serializers/app.ts
+++ b/src/api/serializers/app.ts
@@ -7,7 +7,7 @@ import * as mongo from 'mongodb';
import deepcopy = require('deepcopy');
import App from '../models/app';
import User from '../models/user';
-import Userkey from '../models/userkey';
+import AccessToken from '../models/access-token';
/**
* Serialize an app
@@ -71,7 +71,7 @@ export default (
if (me) {
// 既に連携しているか
- const exist = await Userkey.count({
+ const exist = await AccessToken.count({
app_id: _app.id,
user_id: me,
}, {
diff --git a/src/api/streaming.ts b/src/api/streaming.ts
index 38068d1e3d..7a8d2d4354 100644
--- a/src/api/streaming.ts
+++ b/src/api/streaming.ts
@@ -2,6 +2,8 @@ import * as http from 'http';
import * as websocket from 'websocket';
import * as redis from 'redis';
import User from './models/user';
+import AccessToken from './models/access-token';
+import isNativeToken from './common/is-native-token';
import homeStream from './stream/home';
import messagingStream from './stream/messaging';
@@ -17,7 +19,13 @@ module.exports = (server: http.Server) => {
ws.on('request', async (request) => {
const connection = request.accept();
- const user = await authenticate(connection);
+ const user = await authenticate(connection, request.resourceURL.query.i);
+
+ if (user == null) {
+ connection.send('authentication-failed');
+ connection.close();
+ return;
+ }
// Connect to Redis
const subscriber = redis.createClient(
@@ -41,29 +49,36 @@ module.exports = (server: http.Server) => {
});
};
-function authenticate(connection: websocket.connection): Promise<any> {
- return new Promise((resolve, reject) => {
- // Listen first message
- connection.once('message', async (data) => {
- const msg = JSON.parse(data.utf8Data);
-
+function authenticate(connection: websocket.connection, token: string): Promise<any> {
+ return new Promise(async (resolve, reject) => {
+ if (isNativeToken(token)) {
// Fetch user
// SELECT _id
const user = await User
.findOne({
- token: msg.i
+ token: token
}, {
_id: true
});
- if (user === null) {
- connection.close();
- return;
+ resolve(user);
+ } else {
+ const accessToken = await AccessToken.findOne({
+ hash: token
+ });
+
+ if (accessToken == null) {
+ return reject('invalid signature');
}
- connection.send('authenticated');
+ // Fetch user
+ // SELECT _id
+ const user = await User
+ .findOne({ _id: accessToken.user_id }, {
+ _id: true
+ });
resolve(user);
- });
+ }
});
}