You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.1 KiB
84 lines
2.1 KiB
// auth-token.js
|
|
// Copyright (C) 2024 DTP Technologies, LLC
|
|
// All Rights Reserved
|
|
|
|
'use strict';
|
|
|
|
import mongoose from 'mongoose';
|
|
const AuthToken = mongoose.model('AuthToken');
|
|
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
|
|
import { SiteService, SiteError } from '../../lib/site-lib.js';
|
|
|
|
export default class AuthTokenService extends SiteService {
|
|
|
|
static get slug () { return 'authToken'; }
|
|
static get name ( ) { return 'AuthTokenService'; }
|
|
|
|
constructor (dtp) {
|
|
super(dtp, AuthTokenService);
|
|
}
|
|
|
|
async create (purpose, data) {
|
|
const NOW = new Date();
|
|
const passwordResetToken = new AuthToken();
|
|
passwordResetToken.created = NOW;
|
|
passwordResetToken.purpose = purpose;
|
|
passwordResetToken.token = uuidv4();
|
|
if (data) {
|
|
passwordResetToken.data = data;
|
|
}
|
|
await passwordResetToken.save();
|
|
return passwordResetToken.toObject();
|
|
}
|
|
|
|
async getByValue (tokenValue) {
|
|
if (!tokenValue) {
|
|
throw new SiteError(400, 'Must include an authentication token');
|
|
}
|
|
if ((typeof tokenValue !== 'string') || (tokenValue.length !== 36)) {
|
|
throw new SiteError(400, 'The authentication token is invalid');
|
|
}
|
|
|
|
const token = await AuthToken
|
|
.findOne({ token: tokenValue })
|
|
.lean();
|
|
|
|
if (!token) {
|
|
throw new SiteError(400, 'Auth token not found');
|
|
}
|
|
if (token.claimed) {
|
|
throw new SiteError(403, 'Auth token already used');
|
|
}
|
|
|
|
return token;
|
|
}
|
|
|
|
async claim (tokenValue) {
|
|
const token = await this.getByValue(tokenValue);
|
|
if (!token) {
|
|
throw new SiteError(403, 'The authentication token has expired');
|
|
}
|
|
|
|
if (token.claimed) {
|
|
throw new SiteError(403, 'This authentication token has already been claimed');
|
|
}
|
|
|
|
token.claimed = new Date();
|
|
await AuthToken.updateOne({ _id: token._id }, { $set: { claimed: token.claimed } });
|
|
|
|
return token; // with claimed date
|
|
}
|
|
|
|
async removeForUser (user) {
|
|
await AuthToken.deleteMany({ user: user._id });
|
|
}
|
|
|
|
async remove (token) {
|
|
if (!token || !token._id) {
|
|
throw new SiteError(400, 'Must include auth token');
|
|
}
|
|
await AuthToken.deleteOne({ _id: token._id });
|
|
}
|
|
}
|