231 lines
9.5 KiB
JavaScript
231 lines
9.5 KiB
JavaScript
"use strict";
|
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
});
|
|
};
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const mongoose_1 = __importDefault(require("mongoose"));
|
|
const validator = require("validator");
|
|
const crypto = require("crypto");
|
|
const bcrypt = require("bcrypt");
|
|
const jwt = require("jsonwebtoken");
|
|
const env = require("../enviroment/env");
|
|
const userSchema = new mongoose_1.default.Schema({
|
|
name: {
|
|
type: String,
|
|
trim: true
|
|
},
|
|
email: {
|
|
type: String,
|
|
required: true,
|
|
trim: true,
|
|
unique: true,
|
|
lowercase: true,
|
|
validate(value) {
|
|
if (!validator.isEmail(value)) {
|
|
throw new Error("Email is invalid");
|
|
}
|
|
}
|
|
},
|
|
password: {
|
|
type: String,
|
|
trim: true,
|
|
required: true,
|
|
validate(value) {
|
|
if (value.length < 6) {
|
|
throw new Error("Password Length Not Sufficent");
|
|
}
|
|
}
|
|
},
|
|
tokens: [{
|
|
token: {
|
|
type: String,
|
|
required: true
|
|
}
|
|
}],
|
|
tempTokens: [{
|
|
token: {
|
|
type: String,
|
|
required: true
|
|
}
|
|
}],
|
|
privateKey: {
|
|
type: String,
|
|
},
|
|
publicKey: {
|
|
type: String,
|
|
}
|
|
}, {
|
|
timestamps: true
|
|
});
|
|
// userSchema.virtual("files", {
|
|
// ref: "fs.files",
|
|
// localField: "_id"
|
|
// })
|
|
userSchema.pre("save", function (next) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
const user = this;
|
|
if (user.isModified("password")) {
|
|
user.password = yield bcrypt.hash(user.password, 8);
|
|
}
|
|
next();
|
|
});
|
|
});
|
|
userSchema.statics.findByCreds = (email, password) => __awaiter(void 0, void 0, void 0, function* () {
|
|
const user = yield User.findOne({ email });
|
|
if (!user) {
|
|
throw new Error("User not found");
|
|
}
|
|
const isMatch = yield bcrypt.compare(password, user.password);
|
|
if (!isMatch) {
|
|
console.log("incorrect password");
|
|
throw new Error("Incorrect password");
|
|
}
|
|
return user;
|
|
});
|
|
userSchema.methods.toJSON = function () {
|
|
const user = this;
|
|
const userObject = user.toObject();
|
|
delete userObject.password;
|
|
delete userObject.tokens;
|
|
delete userObject.tempTokens;
|
|
return userObject;
|
|
};
|
|
userSchema.methods.generateAuthToken = function () {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
const iv = crypto.randomBytes(16);
|
|
const user = this;
|
|
let token = jwt.sign({ _id: user._id.toString(), iv }, env.password);
|
|
const publicKey = user.publicKey;
|
|
const encryptionKey = user.getEncryptionKey();
|
|
const encryptedToken = user.encryptToken(token, encryptionKey, iv);
|
|
user.tokens = user.tokens.concat({ token: encryptedToken });
|
|
yield user.save();
|
|
return token;
|
|
});
|
|
};
|
|
userSchema.methods.encryptToken = function (token, key, iv) {
|
|
iv = Buffer.from(iv, "hex");
|
|
const TOKEN_CIPHER_KEY = crypto.createHash('sha256').update(key).digest();
|
|
const cipher = crypto.createCipheriv('aes-256-cbc', TOKEN_CIPHER_KEY, iv);
|
|
let encryptedText = cipher.update(token);
|
|
encryptedText = Buffer.concat([encryptedText, cipher.final()]).toString("hex");
|
|
return encryptedText;
|
|
};
|
|
userSchema.methods.decryptToken = function (encryptedToken, key, iv) {
|
|
encryptedToken = Buffer.from(encryptedToken, "hex");
|
|
iv = Buffer.from(iv, "hex");
|
|
const TOKEN_CIPHER_KEY = crypto.createHash('sha256').update(key).digest();
|
|
const decipher = crypto.createDecipheriv('aes-256-cbc', TOKEN_CIPHER_KEY, iv);
|
|
let tokenDecrypted = decipher.update(encryptedToken);
|
|
tokenDecrypted = Buffer.concat([tokenDecrypted, decipher.final()]).toString();
|
|
return tokenDecrypted;
|
|
};
|
|
userSchema.methods.generateEncryptionKeys = function () {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
const user = this;
|
|
const userPassword = user.password;
|
|
const masterPassword = env.key;
|
|
const randomKey = crypto.randomBytes(32);
|
|
const iv = crypto.randomBytes(16);
|
|
const USER_CIPHER_KEY = crypto.createHash('sha256').update(userPassword).digest();
|
|
const cipher = crypto.createCipheriv('aes-256-cbc', USER_CIPHER_KEY, iv);
|
|
let encryptedText = cipher.update(randomKey);
|
|
encryptedText = Buffer.concat([encryptedText, cipher.final()]);
|
|
const MASTER_CIPHER_KEY = crypto.createHash('sha256').update(masterPassword).digest();
|
|
const masterCipher = crypto.createCipheriv('aes-256-cbc', MASTER_CIPHER_KEY, iv);
|
|
let masterEncryptedText = masterCipher.update(encryptedText);
|
|
masterEncryptedText = Buffer.concat([masterEncryptedText, masterCipher.final()]).toString("hex");
|
|
user.privateKey = masterEncryptedText;
|
|
user.publicKey = iv.toString("hex");
|
|
yield user.save();
|
|
});
|
|
};
|
|
userSchema.methods.getEncryptionKey = function () {
|
|
try {
|
|
const user = this;
|
|
const userPassword = user.password;
|
|
const masterEncryptedText = user.privateKey;
|
|
const masterPassword = env.key;
|
|
const iv = Buffer.from(user.publicKey, "hex");
|
|
const USER_CIPHER_KEY = crypto.createHash('sha256').update(userPassword).digest();
|
|
const MASTER_CIPHER_KEY = crypto.createHash('sha256').update(masterPassword).digest();
|
|
const unhexMasterText = Buffer.from(masterEncryptedText, "hex");
|
|
const masterDecipher = crypto.createDecipheriv('aes-256-cbc', MASTER_CIPHER_KEY, iv);
|
|
let masterDecrypted = masterDecipher.update(unhexMasterText);
|
|
masterDecrypted = Buffer.concat([masterDecrypted, masterDecipher.final()]);
|
|
let decipher = crypto.createDecipheriv('aes-256-cbc', USER_CIPHER_KEY, iv);
|
|
let decrypted = decipher.update(masterDecrypted);
|
|
decrypted = Buffer.concat([decrypted, decipher.final()]);
|
|
return decrypted;
|
|
}
|
|
catch (e) {
|
|
console.log("Get Encryption Key Error");
|
|
return undefined;
|
|
}
|
|
};
|
|
userSchema.methods.changeEncryptionKey = function (randomKey) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
const user = this;
|
|
const userPassword = user.password;
|
|
const masterPassword = env.key;
|
|
const iv = crypto.randomBytes(16);
|
|
const USER_CIPHER_KEY = crypto.createHash('sha256').update(userPassword).digest();
|
|
const cipher = crypto.createCipheriv('aes-256-cbc', USER_CIPHER_KEY, iv);
|
|
let encryptedText = cipher.update(randomKey);
|
|
encryptedText = Buffer.concat([encryptedText, cipher.final()]);
|
|
const MASTER_CIPHER_KEY = crypto.createHash('sha256').update(masterPassword).digest();
|
|
const masterCipher = crypto.createCipheriv('aes-256-cbc', MASTER_CIPHER_KEY, iv);
|
|
let masterEncryptedText = masterCipher.update(encryptedText);
|
|
masterEncryptedText = Buffer.concat([masterEncryptedText, masterCipher.final()]).toString("hex");
|
|
user.privateKey = masterEncryptedText;
|
|
user.publicKey = iv.toString("hex");
|
|
yield user.save();
|
|
});
|
|
};
|
|
userSchema.methods.generateTempAuthToken = function () {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
// const user = this;
|
|
// let token = jwt.sign({_id:user._id.toString()}, env.password);
|
|
// const publicKey = user.publicKey;
|
|
// const encryptionKey = user.getEncryptionKey();
|
|
// const encryptedToken = user.encryptToken(token, encryptionKey, publicKey);
|
|
// user.tokens = user.tokens.concat({token: encryptedToken});
|
|
// await user.save();
|
|
// return token;
|
|
const iv = crypto.randomBytes(16);
|
|
const user = this;
|
|
const token = jwt.sign({ _id: user._id.toString(), iv }, env.password, { expiresIn: 2 });
|
|
const publicKey = user.publicKey;
|
|
const encryptionKey = user.getEncryptionKey();
|
|
const encryptedToken = user.encryptToken(token, encryptionKey, iv);
|
|
user.tempTokens = user.tempTokens.concat({ token: encryptedToken });
|
|
yield user.save();
|
|
return token;
|
|
});
|
|
};
|
|
userSchema.methods.generateTempAuthTokenVideo = function (cookie) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
const iv = crypto.randomBytes(16);
|
|
const user = this;
|
|
const token = jwt.sign({ _id: user._id.toString(), cookie, iv }, env.password, { expiresIn: "5h" });
|
|
//const publicKey = user.publicKey;
|
|
const encryptionKey = user.getEncryptionKey();
|
|
const encryptedToken = user.encryptToken(token, encryptionKey, iv);
|
|
//user.tempTokens = user.tempTokens.concat({token});
|
|
user.tempTokens = user.tempTokens.concat({ token: encryptedToken });
|
|
yield user.save();
|
|
return token;
|
|
});
|
|
};
|
|
const User = mongoose_1.default.model("User", userSchema);
|
|
exports.default = User;
|