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.
105 lines
2.7 KiB
TypeScript
105 lines
2.7 KiB
TypeScript
4 years ago
|
import { TokenDoc } from '../interface';
|
||
4 years ago
|
import * as db from '../service/db';
|
||
|
|
||
|
const coll = db.collection('token');
|
||
|
|
||
|
export const TYPE_SESSION = 0;
|
||
|
export const TYPE_REGISTRATION = 2;
|
||
|
export const TYPE_CHANGEMAIL = 3;
|
||
|
export const TYPE_OAUTH = 4;
|
||
|
export const TYPE_LOSTPASS = 5;
|
||
|
|
||
4 years ago
|
function ensureIndexes() {
|
||
4 years ago
|
return Promise.all([
|
||
|
coll.createIndex([{ uid: 1 }, { tokenType: 1 }, { updateAt: -1 }], { sparse: true }),
|
||
|
coll.createIndex('expireAt', { expireAfterSeconds: 0 }),
|
||
|
]);
|
||
|
}
|
||
|
|
||
4 years ago
|
export async function add(
|
||
|
tokenType: number, expireSeconds: number, data: any,
|
||
|
): Promise<[string, TokenDoc]> {
|
||
4 years ago
|
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]];
|
||
|
}
|
||
|
|
||
4 years ago
|
export async function get(tokenId: string, tokenType: number): Promise<TokenDoc | null> {
|
||
|
return await coll.findOne({ _id: tokenId, tokenType });
|
||
4 years ago
|
}
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|
||
4 years ago
|
export async function createOrUpdate(
|
||
|
tokenType: number, expireSeconds: number, data: any,
|
||
|
): Promise<string> {
|
||
4 years ago
|
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) {
|
||
4 years ago
|
return coll.find({ uid, tokenType: TYPE_SESSION }).sort('updateAt', -1).toArray();
|
||
4 years ago
|
}
|
||
|
|
||
|
export function getMostRecentSessionByUid(uid: number) {
|
||
4 years ago
|
return coll.findOne({ uid, tokenType: TYPE_SESSION }, { sort: { updateAt: -1 } });
|
||
4 years ago
|
}
|
||
|
|
||
|
export function delByUid(uid: number) {
|
||
|
return coll.deleteMany({ uid });
|
||
|
}
|
||
|
|
||
4 years ago
|
global.Hydro.postInit.push(ensureIndexes);
|
||
4 years ago
|
global.Hydro.model.token = {
|
||
|
TYPE_SESSION,
|
||
|
TYPE_CHANGEMAIL,
|
||
|
TYPE_OAUTH,
|
||
|
TYPE_REGISTRATION,
|
||
4 years ago
|
TYPE_LOSTPASS,
|
||
4 years ago
|
|
||
|
add,
|
||
|
createOrUpdate,
|
||
|
get,
|
||
|
update,
|
||
|
del,
|
||
|
delByUid,
|
||
|
getMostRecentSessionByUid,
|
||
|
getSessionListByUid,
|
||
|
};
|