Implement permission management and enhance user interface for permissions in the application
Add new permission routes and integrate permission checks across various existing routes to ensure proper access control. Update the UserClub model to include role and permissions fields, allowing for more granular user access management. Enhance the frontend by introducing a user dropdown menu for managing permissions and displaying relevant options based on user roles. Improve the overall user experience by implementing permission-based visibility for navigation links and actions throughout the application.
This commit is contained in:
141
backend/scripts/createTestUsers.js
Normal file
141
backend/scripts/createTestUsers.js
Normal file
@@ -0,0 +1,141 @@
|
||||
import User from '../models/User.js';
|
||||
import Club from '../models/Club.js';
|
||||
import UserClub from '../models/UserClub.js';
|
||||
import sequelize from '../database.js';
|
||||
|
||||
/**
|
||||
* Create test users with different roles
|
||||
*/
|
||||
|
||||
const TEST_USERS = [
|
||||
{
|
||||
email: 'admin@test.de',
|
||||
password: 'test123',
|
||||
role: 'admin',
|
||||
isOwner: false
|
||||
},
|
||||
{
|
||||
email: 'trainer@test.de',
|
||||
password: 'test123',
|
||||
role: 'trainer',
|
||||
isOwner: false
|
||||
},
|
||||
{
|
||||
email: 'teammanager@test.de',
|
||||
password: 'test123',
|
||||
role: 'team_manager',
|
||||
isOwner: false
|
||||
},
|
||||
{
|
||||
email: 'tournamentmanager@test.de',
|
||||
password: 'test123',
|
||||
role: 'tournament_manager',
|
||||
isOwner: false
|
||||
},
|
||||
{
|
||||
email: 'member1@test.de',
|
||||
password: 'test123',
|
||||
role: 'member',
|
||||
isOwner: false
|
||||
},
|
||||
{
|
||||
email: 'member2@test.de',
|
||||
password: 'test123',
|
||||
role: 'member',
|
||||
isOwner: false
|
||||
}
|
||||
];
|
||||
|
||||
async function createTestUsers() {
|
||||
console.log('Creating test users...\n');
|
||||
|
||||
try {
|
||||
// Get first club (or specify club ID)
|
||||
const clubs = await Club.findAll({ limit: 1 });
|
||||
|
||||
if (clubs.length === 0) {
|
||||
console.error('❌ No clubs found! Please create a club first.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const club = clubs[0];
|
||||
console.log(`Using club: ${club.name} (ID: ${club.id})\n`);
|
||||
|
||||
for (const userData of TEST_USERS) {
|
||||
console.log(`Creating user: ${userData.email} (${userData.role})...`);
|
||||
|
||||
// Check if user already exists
|
||||
let user = await User.findOne({ where: { email: userData.email } });
|
||||
|
||||
if (user) {
|
||||
console.log(` ⚠️ User already exists, using existing user`);
|
||||
} else {
|
||||
// Create user
|
||||
user = await User.create({
|
||||
email: userData.email,
|
||||
password: userData.password,
|
||||
isActive: true
|
||||
});
|
||||
console.log(` ✓ User created`);
|
||||
}
|
||||
|
||||
// Check if user is already in club
|
||||
let userClub = await UserClub.findOne({
|
||||
where: {
|
||||
userId: user.id,
|
||||
clubId: club.id
|
||||
}
|
||||
});
|
||||
|
||||
if (userClub) {
|
||||
console.log(` ⚠️ User already in club, updating role...`);
|
||||
await userClub.update({
|
||||
role: userData.role,
|
||||
isOwner: userData.isOwner,
|
||||
approved: true
|
||||
});
|
||||
console.log(` ✓ Updated to role: ${userData.role}`);
|
||||
} else {
|
||||
// Add user to club
|
||||
userClub = await UserClub.create({
|
||||
userId: user.id,
|
||||
clubId: club.id,
|
||||
role: userData.role,
|
||||
isOwner: userData.isOwner,
|
||||
approved: true
|
||||
});
|
||||
console.log(` ✓ Added to club with role: ${userData.role}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\n✅ Test users created successfully!\n');
|
||||
|
||||
// Show summary
|
||||
console.log('Summary:');
|
||||
console.log('========================================');
|
||||
console.log(`Club: ${club.name}`);
|
||||
console.log('\nTest Users:');
|
||||
|
||||
for (const userData of TEST_USERS) {
|
||||
console.log(` ${userData.email.padEnd(25)} | ${userData.role.padEnd(15)} | Password: test123`);
|
||||
}
|
||||
|
||||
console.log('\n========================================');
|
||||
console.log('You can now login with any of these users!');
|
||||
console.log('All passwords are: test123');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Error creating test users:', error);
|
||||
throw error;
|
||||
} finally {
|
||||
await sequelize.close();
|
||||
}
|
||||
}
|
||||
|
||||
// Run
|
||||
createTestUsers().catch(err => {
|
||||
console.error('Fatal error:', err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
|
||||
128
backend/scripts/migratePermissions.js
Normal file
128
backend/scripts/migratePermissions.js
Normal file
@@ -0,0 +1,128 @@
|
||||
import UserClub from '../models/UserClub.js';
|
||||
import Club from '../models/Club.js';
|
||||
import User from '../models/User.js';
|
||||
import sequelize from '../database.js';
|
||||
|
||||
/**
|
||||
* Migration script to set up permissions for existing clubs
|
||||
* This script:
|
||||
* 1. Sets default role='member' for all approved users without a role
|
||||
* 2. Identifies and marks the first user (by creation date) of each club as owner
|
||||
*/
|
||||
|
||||
async function migratePermissions() {
|
||||
console.log('Starting permissions migration...\n');
|
||||
|
||||
try {
|
||||
// Get all clubs
|
||||
const clubs = await Club.findAll({
|
||||
include: [{
|
||||
model: UserClub,
|
||||
include: [{
|
||||
model: User,
|
||||
as: 'user'
|
||||
}],
|
||||
where: {
|
||||
approved: true
|
||||
},
|
||||
order: [['createdAt', 'ASC']]
|
||||
}]
|
||||
});
|
||||
|
||||
console.log(`Found ${clubs.length} club(s)\n`);
|
||||
|
||||
for (const club of clubs) {
|
||||
console.log(`\n--- Club: ${club.name} (ID: ${club.id}) ---`);
|
||||
|
||||
const userClubs = await UserClub.findAll({
|
||||
where: {
|
||||
clubId: club.id,
|
||||
approved: true
|
||||
},
|
||||
include: [{
|
||||
model: User,
|
||||
as: 'user'
|
||||
}],
|
||||
order: [['createdAt', 'ASC']]
|
||||
});
|
||||
|
||||
if (userClubs.length === 0) {
|
||||
console.log(' No approved members found.');
|
||||
continue;
|
||||
}
|
||||
|
||||
// First user becomes owner
|
||||
const firstUser = userClubs[0];
|
||||
|
||||
console.log(` Members found: ${userClubs.length}`);
|
||||
console.log(` First member (will be owner): ${firstUser.user.email}`);
|
||||
|
||||
for (let i = 0; i < userClubs.length; i++) {
|
||||
const userClub = userClubs[i];
|
||||
const isFirstUser = i === 0;
|
||||
|
||||
// Set role if not set
|
||||
if (!userClub.role) {
|
||||
userClub.role = isFirstUser ? 'admin' : 'member';
|
||||
}
|
||||
|
||||
// Set owner flag
|
||||
userClub.isOwner = isFirstUser;
|
||||
|
||||
await userClub.save();
|
||||
|
||||
console.log(` ✓ Updated ${userClub.user.email}: role=${userClub.role}, isOwner=${userClub.isOwner}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\n✅ Migration completed successfully!');
|
||||
console.log('\nSummary:');
|
||||
|
||||
// Show summary
|
||||
const owners = await UserClub.findAll({
|
||||
where: {
|
||||
isOwner: true
|
||||
},
|
||||
include: [
|
||||
{
|
||||
model: User,
|
||||
as: 'user'
|
||||
},
|
||||
{
|
||||
model: Club,
|
||||
as: 'club'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
console.log(`\nClub Owners (${owners.length}):`);
|
||||
for (const owner of owners) {
|
||||
console.log(` - ${owner.club.name}: ${owner.user.email}`);
|
||||
}
|
||||
|
||||
const admins = await UserClub.count({
|
||||
where: { role: 'admin' }
|
||||
});
|
||||
const members = await UserClub.count({
|
||||
where: { role: 'member' }
|
||||
});
|
||||
|
||||
console.log(`\nRole Distribution:`);
|
||||
console.log(` - Admins: ${admins}`);
|
||||
console.log(` - Members: ${members}`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Migration failed:', error);
|
||||
throw error;
|
||||
} finally {
|
||||
await sequelize.close();
|
||||
}
|
||||
}
|
||||
|
||||
// Run migration
|
||||
migratePermissions().catch(err => {
|
||||
console.error('Fatal error:', err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
|
||||
103
backend/scripts/quickFixOwner.js
Normal file
103
backend/scripts/quickFixOwner.js
Normal file
@@ -0,0 +1,103 @@
|
||||
import UserClub from '../models/UserClub.js';
|
||||
import Club from '../models/Club.js';
|
||||
import User from '../models/User.js';
|
||||
import sequelize from '../database.js';
|
||||
|
||||
/**
|
||||
* Quick fix: Set first user of each club as owner/admin
|
||||
* This is a simplified version for immediate use
|
||||
*/
|
||||
|
||||
async function quickFixOwners() {
|
||||
console.log('Quick Fix: Setting club owners...\n');
|
||||
|
||||
try {
|
||||
const clubs = await Club.findAll();
|
||||
|
||||
console.log(`Found ${clubs.length} club(s)\n`);
|
||||
|
||||
for (const club of clubs) {
|
||||
console.log(`Club: ${club.name} (ID: ${club.id})`);
|
||||
|
||||
// Find all approved members, ordered by creation date
|
||||
const userClubs = await UserClub.findAll({
|
||||
where: {
|
||||
clubId: club.id,
|
||||
approved: true
|
||||
},
|
||||
include: [{
|
||||
model: User,
|
||||
as: 'user',
|
||||
attributes: ['id', 'email']
|
||||
}],
|
||||
order: [['createdAt', 'ASC']]
|
||||
});
|
||||
|
||||
if (userClubs.length === 0) {
|
||||
console.log(' ⚠️ No approved members\n');
|
||||
continue;
|
||||
}
|
||||
|
||||
// First user becomes owner
|
||||
const firstUserClub = userClubs[0];
|
||||
|
||||
// Reset all users first (remove owner flag)
|
||||
await UserClub.update(
|
||||
{ isOwner: false },
|
||||
{
|
||||
where: {
|
||||
clubId: club.id,
|
||||
approved: true
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Set first user as owner and admin
|
||||
await firstUserClub.update({
|
||||
isOwner: true,
|
||||
role: 'admin'
|
||||
});
|
||||
|
||||
console.log(` ✅ Owner: ${firstUserClub.user.email}`);
|
||||
|
||||
// Set role for other members if not set
|
||||
for (let i = 1; i < userClubs.length; i++) {
|
||||
const uc = userClubs[i];
|
||||
if (!uc.role) {
|
||||
await uc.update({ role: 'member' });
|
||||
console.log(` 👤 Member: ${uc.user.email}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('');
|
||||
}
|
||||
|
||||
console.log('✅ Quick fix completed!\n');
|
||||
|
||||
// Show all owners
|
||||
const owners = await UserClub.findAll({
|
||||
where: { isOwner: true },
|
||||
include: [
|
||||
{ model: User, as: 'user', attributes: ['email'] },
|
||||
{ model: Club, as: 'club', attributes: ['name'] }
|
||||
]
|
||||
});
|
||||
|
||||
console.log('Current Club Owners:');
|
||||
for (const owner of owners) {
|
||||
console.log(` 📍 ${owner.club.name}: ${owner.user.email} (role: ${owner.role})`);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Error:', error);
|
||||
throw error;
|
||||
} finally {
|
||||
await sequelize.close();
|
||||
}
|
||||
}
|
||||
|
||||
quickFixOwners().catch(err => {
|
||||
console.error('Fatal error:', err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user