mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-09 10:34:17 +00:00
95 lines
2.4 KiB
JavaScript
95 lines
2.4 KiB
JavaScript
import { User, PasswordRecover } from "@db_models"
|
|
import AuthToken from "@shared-classes/AuthToken"
|
|
|
|
import obscureEmail from "@shared-utils/obscureEmail"
|
|
import isEmail from "@shared-utils/isEmail"
|
|
|
|
function getClientDeviceData(req) {
|
|
const ip =
|
|
req.headers["x-forwarded-for"] ?? req.socket?.remoteAddress ?? req.ip
|
|
const userAgent = req.headers["user-agent"]
|
|
|
|
return { ip_address: ip, client: userAgent }
|
|
}
|
|
|
|
export default {
|
|
fn: async (req) => {
|
|
// find user by email or username
|
|
const { account } = req.body
|
|
|
|
const userSearchQuery = {}
|
|
|
|
if (isEmail(account)) {
|
|
userSearchQuery.email = account
|
|
} else {
|
|
userSearchQuery.username = account
|
|
}
|
|
|
|
const user = await User.findOne(userSearchQuery).select("+email")
|
|
|
|
if (!user) {
|
|
throw new OperationError(404, "User not found")
|
|
}
|
|
|
|
let passwordRecoverSession = await PasswordRecover.findOne({
|
|
user_id: user._id.toString(),
|
|
})
|
|
|
|
// check if session exist, and if it's expired
|
|
if (passwordRecoverSession) {
|
|
const now = new Date()
|
|
const expires = passwordRecoverSession.expires_at
|
|
|
|
// if not expired, thow a error
|
|
if (expires > now) {
|
|
throw new OperationError(
|
|
400,
|
|
"Password recovery session is still active",
|
|
)
|
|
} else {
|
|
// destroy session
|
|
await PasswordRecover.findOneAndDelete({
|
|
_id: passwordRecoverSession._id.toString(),
|
|
})
|
|
}
|
|
}
|
|
|
|
// expires in 5 minutes
|
|
const expiresIn = 1000 * 60 * 5
|
|
|
|
passwordRecoverSession = new PasswordRecover({
|
|
user_id: user._id.toString(),
|
|
created_at: new Date(),
|
|
expires_at: new Date(Date.now() + expiresIn),
|
|
code: global.nanoid(8),
|
|
...getClientDeviceData(req),
|
|
})
|
|
|
|
await passwordRecoverSession.save()
|
|
|
|
const verificationToken = await AuthToken.signToken({
|
|
recoverySessionId: passwordRecoverSession._id.toString(),
|
|
user_id: user._id.toString(),
|
|
})
|
|
|
|
ipc.invoke("ems", "apr:send", {
|
|
code: passwordRecoverSession.code,
|
|
created_at: passwordRecoverSession.created_at,
|
|
expires_at: passwordRecoverSession.expires_at,
|
|
user: user.toObject(),
|
|
...getClientDeviceData(req),
|
|
})
|
|
|
|
return {
|
|
user_id: user._id.toString(),
|
|
email: obscureEmail(user.email),
|
|
expires_at: passwordRecoverSession.expires_at,
|
|
expires_in: Math.floor(
|
|
(passwordRecoverSession.expires_at - Date.now()) / 1000 / 60,
|
|
),
|
|
code_length: passwordRecoverSession.code.toString().length,
|
|
verificationToken: verificationToken,
|
|
}
|
|
},
|
|
}
|