You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Hydro/hydro/model/token.ts

105 lines
2.8 KiB
TypeScript

import { ValidationError } from '../error';
import * as db from '../service/db';
const coll = db.collection('token');
export const TYPE_SESSION = 0;
export const TYPE_CSRF_TOKEN = 1;
export const TYPE_REGISTRATION = 2;
export const TYPE_CHANGEMAIL = 3;
export const TYPE_OAUTH = 4;
export const TYPE_LOSTPASS = 5;
export function ensureIndexes() {
return Promise.all([
coll.createIndex([{ uid: 1 }, { tokenType: 1 }, { updateAt: -1 }], { sparse: true }),
coll.createIndex('expireAt', { expireAfterSeconds: 0 }),
]);
}
export async function add(tokenType: number, expireSeconds: number, data: any) {
const now = new Date();
const str = String.random(32);
const res = await coll.insertOne({
...data,
_id: str,
tokenType,
createAt: now,
updateAt: now,
expireAt: new Date(now.getTime() + expireSeconds * 1000),
});
return [str, res.ops[0]];
}
export async function get(tokenId: string, tokenType: number, doThrow = true) {
const res = await coll.findOne({ _id: tokenId, tokenType });
if (!res && doThrow) throw new ValidationError('token');
return res;
}
export async function update(
tokenId: string, tokenType: number, expireSeconds: number,
data: object,
) {
const now = new Date();
const res = await coll.findOneAndUpdate(
{ _id: tokenId, tokenType },
{
$set: {
...data,
updateAt: now,
expireAt: new Date(now.getTime() + expireSeconds * 1000),
tokenType,
},
},
{ returnOriginal: false },
);
return res.value;
}
export async function del(tokenId: string, tokenType: number) {
const result = await coll.deleteOne({ _id: tokenId, tokenType });
return !!result.deletedCount;
}
export async function createOrUpdate(tokenType: number, expireSeconds: number, data: object) {
const d = await coll.findOne({ tokenType, ...data });
if (!d) {
const res = await add(tokenType, expireSeconds, data);
return res[0];
}
await update(d._id, tokenType, expireSeconds, data);
return d._id;
}
export function getSessionListByUid(uid: number) {
return coll.find({ uid, tokenType: this.TYPE_SESSION }).sort('updateAt', -1).toArray();
}
export function getMostRecentSessionByUid(uid: number) {
return coll.findOne({ uid, tokenType: this.TYPE_SESSION }, { sort: { updateAt: -1 } });
}
export function delByUid(uid: number) {
return coll.deleteMany({ uid });
}
global.Hydro.model.token = {
TYPE_SESSION,
TYPE_CHANGEMAIL,
TYPE_CSRF_TOKEN,
TYPE_OAUTH,
TYPE_REGISTRATION,
TYPE_LOSTPASS,
ensureIndexes,
add,
createOrUpdate,
get,
update,
del,
delByUid,
getMostRecentSessionByUid,
getSessionListByUid,
};