Update typos and added scripts
This commit is contained in:
parent
cb51c46f63
commit
7db993fb0e
27
scripts/delete_user.js
Normal file
27
scripts/delete_user.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
const User = require('../src/db/models/User');
|
||||||
|
const { Model } = require('objection');
|
||||||
|
const Knex = require('knex');
|
||||||
|
const knexConfig = require('../src/config/database');
|
||||||
|
const knex = Knex(knexConfig.development);
|
||||||
|
Model.knex(knex);
|
||||||
|
|
||||||
|
const email = process.argv[2];
|
||||||
|
const id = process.argv[3];
|
||||||
|
|
||||||
|
if (!email && !id) {
|
||||||
|
console.error('Usage: node delete_user.js <email> || <id>');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
let user;
|
||||||
|
if (id) {
|
||||||
|
user = await User.query().where('id', id).delete();
|
||||||
|
} else {
|
||||||
|
user = await User.query().where('email', email).delete();
|
||||||
|
}
|
||||||
|
console.log(`User deleted`);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
36
scripts/generate_password.js
Normal file
36
scripts/generate_password.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
const bcrypt = require('bcrypt');
|
||||||
|
const User = require('../src/db/models/User');
|
||||||
|
const { Model } = require('objection');
|
||||||
|
const Knex = require('knex');
|
||||||
|
const knexConfig = require('../src/config/database');
|
||||||
|
const knex = Knex(knexConfig.development);
|
||||||
|
Model.knex(knex);
|
||||||
|
|
||||||
|
const password = process.argv[2];
|
||||||
|
const email = process.argv[3];
|
||||||
|
|
||||||
|
if (!password && !email) {
|
||||||
|
console.error('Usage: node generate_password.js <password> [email]');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
let user;
|
||||||
|
if (email) {
|
||||||
|
user = await User.query().where('email', email).first();
|
||||||
|
if (!user) {
|
||||||
|
console.error('User not found');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
user.password = bcrypt.hashSync(password, 10);
|
||||||
|
await user.$query().patch();
|
||||||
|
console.log(`Password updated for user ${user.email}`);
|
||||||
|
process.exit(0);
|
||||||
|
} else {
|
||||||
|
console.log(bcrypt.hashSync(password, 10));
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
27
scripts/make_user.js
Normal file
27
scripts/make_user.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
const User = require('../src/db/models/User');
|
||||||
|
const { Model } = require('objection');
|
||||||
|
const Knex = require('knex');
|
||||||
|
const knexConfig = require('../src/config/database');
|
||||||
|
const knex = Knex(knexConfig.development);
|
||||||
|
Model.knex(knex);
|
||||||
|
|
||||||
|
const email = process.argv[2];
|
||||||
|
const password = process.argv[3];
|
||||||
|
const isAdmin = process.argv[4] === 'true';
|
||||||
|
|
||||||
|
if (!email || !password) {
|
||||||
|
console.error('Usage: node make_user.js <email> <password> [isAdmin]');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const user = await User.query().insert({
|
||||||
|
email: email,
|
||||||
|
password: password,
|
||||||
|
is_admin: isAdmin
|
||||||
|
});
|
||||||
|
console.log(`User created: ${user.email}`);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
17
src/db/migrations/20250127223039_add_cascade_to_tempemail.js
Normal file
17
src/db/migrations/20250127223039_add_cascade_to_tempemail.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
exports.up = function(knex) {
|
||||||
|
return knex.schema.alterTable('temp_emails', table => {
|
||||||
|
table.dropForeign('user_id');
|
||||||
|
|
||||||
|
table.foreign('user_id')
|
||||||
|
.references('users.id')
|
||||||
|
.onDelete('CASCADE');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.down = function(knex) {
|
||||||
|
return knex.schema.alterTable('temp_emails', table => {
|
||||||
|
table.dropForeign('user_id');
|
||||||
|
table.foreign('user_id')
|
||||||
|
.references('users.id');
|
||||||
|
});
|
||||||
|
};
|
||||||
@ -6,6 +6,21 @@ class User extends BaseModel {
|
|||||||
return 'users';
|
return 'users';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static get relationMappings() {
|
||||||
|
const TempEmail = require('./TempEmail');
|
||||||
|
return {
|
||||||
|
tempEmails: {
|
||||||
|
relation: BaseModel.HasManyRelation,
|
||||||
|
modelClass: TempEmail,
|
||||||
|
join: {
|
||||||
|
from: 'users.id',
|
||||||
|
to: 'temp_emails.user_id'
|
||||||
|
},
|
||||||
|
onDelete: 'CASCADE'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
async $beforeInsert() {
|
async $beforeInsert() {
|
||||||
await super.$beforeInsert();
|
await super.$beforeInsert();
|
||||||
this.password = await bcrypt.hash(this.password, 10);
|
this.password = await bcrypt.hash(this.password, 10);
|
||||||
|
|||||||
@ -9,6 +9,8 @@ const config = require('../../config/haraka');
|
|||||||
*/
|
*/
|
||||||
exports.seed = async function(knex) {
|
exports.seed = async function(knex) {
|
||||||
await knex('users').del();
|
await knex('users').del();
|
||||||
|
await knex('temp_emails').del();
|
||||||
|
await knex('messages').del();
|
||||||
|
|
||||||
const hashedPassword = await bcrypt.hash('admin', 10);
|
const hashedPassword = await bcrypt.hash('admin', 10);
|
||||||
const [userId] = await knex('users').insert([
|
const [userId] = await knex('users').insert([
|
||||||
|
|||||||
@ -1,9 +1,32 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const jwt = require('jsonwebtoken');
|
const jwt = require('jsonwebtoken');
|
||||||
const { User } = require('../db/models/User');
|
const User = require('../db/models/User');
|
||||||
const config = require('../config/haraka');
|
const config = require('../config/haraka');
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /auth/login:
|
||||||
|
* post:
|
||||||
|
* summary: Login and get API key
|
||||||
|
* description: Login with email and password to get an API key
|
||||||
|
* requestBody:
|
||||||
|
* required: true
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* email:
|
||||||
|
* type: string
|
||||||
|
* description: User's email
|
||||||
|
* example: user@example.com
|
||||||
|
* password:
|
||||||
|
* type: string
|
||||||
|
* description: User's password
|
||||||
|
* example: password123
|
||||||
|
*/
|
||||||
router.post('/login', async (req, res) => {
|
router.post('/login', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { email, password } = req.body;
|
const { email, password } = req.body;
|
||||||
@ -13,16 +36,41 @@ router.post('/login', async (req, res) => {
|
|||||||
return res.status(401).json({ error: 'Invalid credentials' });
|
return res.status(401).json({ error: 'Invalid credentials' });
|
||||||
}
|
}
|
||||||
|
|
||||||
const token = jwt.sign(
|
const generateToken = () => {
|
||||||
|
return jwt.sign(
|
||||||
{ id: user.id, email: user.email, is_admin: user.is_admin },
|
{ id: user.id, email: user.email, is_admin: user.is_admin },
|
||||||
config.auth.jwtSecret,
|
config.auth.jwtSecret,
|
||||||
{ expiresIn: config.auth.tokenExpiry }
|
{ expiresIn: config.auth.tokenExpiry }
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
await User.query().where('id', user.id).update({ api_key: token });
|
let currentToken = await User.query()
|
||||||
|
.select('api_key')
|
||||||
|
.where('id', user.id)
|
||||||
|
.first();
|
||||||
|
|
||||||
|
let token;
|
||||||
|
|
||||||
|
if (currentToken && currentToken.api_key) {
|
||||||
|
try {
|
||||||
|
jwt.verify(currentToken.api_key, config.auth.jwtSecret);
|
||||||
|
token = currentToken.api_key;
|
||||||
|
} catch (tokenError) {
|
||||||
|
token = generateToken();
|
||||||
|
await User.query()
|
||||||
|
.where('id', user.id)
|
||||||
|
.update({ api_key: token });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
token = generateToken();
|
||||||
|
await User.query()
|
||||||
|
.where('id', user.id)
|
||||||
|
.update({ api_key: token });
|
||||||
|
}
|
||||||
|
|
||||||
res.json({ token });
|
res.json({ token });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.error('Login error:', error);
|
||||||
res.status(500).json({ error: error.message });
|
res.status(500).json({ error: error.message });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -33,7 +33,24 @@ function generateUniqueName() {
|
|||||||
return `${formattedName}${randomNumber}`;
|
return `${formattedName}${randomNumber}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
router.post('/', async (req, res) => {
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /email/generate:
|
||||||
|
* post:
|
||||||
|
* summary: Generate a temporary email
|
||||||
|
* description: Generate a temporary email with a random domain
|
||||||
|
* requestBody:
|
||||||
|
* required: false
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* name:
|
||||||
|
* type: string
|
||||||
|
* description: Name for the temporary email
|
||||||
|
*/
|
||||||
|
router.post('/generate', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const randomDomain = await Domain.query()
|
const randomDomain = await Domain.query()
|
||||||
.where('active', true)
|
.where('active', true)
|
||||||
@ -59,14 +76,36 @@ router.post('/', async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/', async (req, res) => {
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /email/list:
|
||||||
|
* get:
|
||||||
|
* summary: List all temporary emails
|
||||||
|
* description: Get a list of all temporary emails for the authenticated user
|
||||||
|
*/
|
||||||
|
router.get('/list', async (req, res) => {
|
||||||
const tempEmails = await TempEmail.query().where('user_id', req.user.id);
|
const tempEmails = await TempEmail.query().where('user_id', req.user.id);
|
||||||
res.json(tempEmails);
|
res.json(tempEmails);
|
||||||
});
|
});
|
||||||
|
|
||||||
router.delete('/:id', async (req, res) => {
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /email/delete/{id}:
|
||||||
|
* delete:
|
||||||
|
* summary: Delete a temporary email
|
||||||
|
* description: Delete a temporary email by its ID
|
||||||
|
* parameters:
|
||||||
|
* - in: path
|
||||||
|
* name: id
|
||||||
|
* required: true
|
||||||
|
* description: ID of the temporary email to delete
|
||||||
|
*/
|
||||||
|
router.delete('/delete/:id', async (req, res) => {
|
||||||
const tempEmail = await TempEmail.query().where('id', req.params.id).andWhere('user_id', req.user.id).delete();
|
const tempEmail = await TempEmail.query().where('id', req.params.id).andWhere('user_id', req.user.id).delete();
|
||||||
res.json(tempEmail);
|
if (!tempEmail) {
|
||||||
|
res.status(404).json({ status: 'error', message: 'Temp email not found' });
|
||||||
|
}
|
||||||
|
res.json({ status: 'success', message: 'Temp email deleted' });
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
8
src/routes/index.js
Normal file
8
src/routes/index.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
router.get('/', async (req, res) => {
|
||||||
|
res.json({ message: 'Hello World' });
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
Loading…
x
Reference in New Issue
Block a user