Files
DiceCloud/app/imports/server/rest/restLogin.js
Stefan Zermatten 359f18988c Account functionality extended, API authentication implemented
- Can now add a second email address to your account and delete one of 
your email addresses
- Reset password now works
- Resetting the password of an account without a password set will set 
one
- Email templates overhauled
- Login tokens limited to close previously devastating ($800 database 
bill) security hole
- Login with REST API now works
- Once logged in, authentication of API calls with token works
- Creatures can now be fetched using the API
2022-02-10 19:02:18 +02:00

86 lines
2.3 KiB
JavaScript

import { JsonRoutes } from 'meteor/simple:json-routes';
import authenticateMeteorUserByToken from './middleware/authenticateUserByToken.js';
/**
* Login with username/email and password:
* POST /api/login
* Body: {"username": "<your username>", "password": "<your password>"}
* Alternative Body: {"email": "<your email>", "password": "<your password>"}
* Successful response:
* {
* "id": "<your userId>",
* "token": "<your user token, save this>",
* "tokenExpires": "<date string of token expiry date>"
* }
*
* Warning: Your token may expire before the given date.
* Since each user has a limited pool of login tokens. If you get a permission
* error, you may need to login again to refresh your token
*
* Once you have your token, you can use it as a standard bearer token header
* in other API endpoints:
* HTTP.post("/methods/return-five-auth", {
* headers: { Authorization: "Bearer <token>" }
* }, callback);
**/
JsonRoutes.Middleware.use(JsonRoutes.Middleware.parseBearerToken);
JsonRoutes.Middleware.use(authenticateMeteorUserByToken);
JsonRoutes.add('options', 'api/login', function (req, res) {
JsonRoutes.sendResult(res);
});
JsonRoutes.add('post', 'api/login', function (req, res) {
var options = req.body;
var user;
if (options.email) {
check(options, {
email: String,
password: String,
});
user = Accounts.findUserByEmail(options.email);
} else {
check(options, {
username: String,
password: String,
});
user = Accounts.findUserByUsername(options.username);
}
if (!user) {
throw new Meteor.Error('not-found',
'User with that username or email address not found.');
}
var result = Accounts._checkPassword(user, options.password);
check(result, {
userId: String,
error: Match.Optional(Meteor.Error),
});
if (result.error) {
throw result.error;
}
var stampedLoginToken = Accounts._generateStampedLoginToken();
check(stampedLoginToken, {
token: String,
when: Date,
});
Accounts._insertLoginToken(result.userId, stampedLoginToken);
var tokenExpiration = Accounts._tokenExpiration(stampedLoginToken.when);
check(tokenExpiration, Date);
JsonRoutes.sendResult(res, {
data: {
id: result.userId,
token: stampedLoginToken.token,
tokenExpires: tokenExpiration,
},
});
});