deckhearth/pages/api/setup-auth.js

172 lines
No EOL
5.3 KiB
JavaScript

const { Pool } = require('pg');
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false,
});
export default async function handler(req, res) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}
const client = await pool.connect();
try {
console.log('Setting up user authentication schema...');
// Check if users table already exists
const tableCheck = await client.query(`
SELECT EXISTS (
SELECT FROM information_schema.tables
WHERE table_schema = 'public'
AND table_name = 'users'
);
`);
if (tableCheck.rows[0].exists) {
return res.status(200).json({
success: true,
message: 'User authentication schema already exists',
already_setup: true
});
}
// Create tables one by one
await client.query(`
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
first_name VARCHAR(50),
last_name VARCHAR(50),
avatar_url TEXT,
is_active BOOLEAN DEFAULT true,
email_verified BOOLEAN DEFAULT false,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
last_login TIMESTAMP WITH TIME ZONE
);
`);
await client.query(`
CREATE TABLE IF NOT EXISTS roles (
id SERIAL PRIMARY KEY,
name VARCHAR(50) UNIQUE NOT NULL,
description TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
`);
await client.query(`
CREATE TABLE IF NOT EXISTS user_roles (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
role_id INTEGER REFERENCES roles(id) ON DELETE CASCADE,
assigned_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
assigned_by INTEGER REFERENCES users(id),
UNIQUE(user_id, role_id)
);
`);
await client.query(`
CREATE TABLE IF NOT EXISTS permissions (
id SERIAL PRIMARY KEY,
name VARCHAR(100) UNIQUE NOT NULL,
description TEXT,
resource VARCHAR(50),
action VARCHAR(50),
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
`);
await client.query(`
CREATE TABLE IF NOT EXISTS role_permissions (
id SERIAL PRIMARY KEY,
role_id INTEGER REFERENCES roles(id) ON DELETE CASCADE,
permission_id INTEGER REFERENCES permissions(id) ON DELETE CASCADE,
UNIQUE(role_id, permission_id)
);
`);
await client.query(`
CREATE TABLE IF NOT EXISTS user_sessions (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
token_hash VARCHAR(255) NOT NULL,
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
last_used TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
user_agent TEXT,
ip_address INET
);
`);
// Insert default roles
await client.query(`
INSERT INTO roles (name, description) VALUES
('user', 'Standard user with basic permissions'),
('admin', 'Administrator with full system access')
ON CONFLICT (name) DO NOTHING;
`);
// Insert basic permissions
const permissions = [
['cards.read', 'View cards'],
['collections.manage', 'Manage collections'],
['decks.manage', 'Manage decks'],
['admin.access', 'Access admin panel']
];
for (const [name, description] of permissions) {
await client.query(`
INSERT INTO permissions (name, description)
VALUES ($1, $2)
ON CONFLICT (name) DO NOTHING;
`, [name, description]);
}
// Assign permissions to roles
await client.query(`
INSERT INTO role_permissions (role_id, permission_id)
SELECT r.id, p.id
FROM roles r, permissions p
WHERE r.name = 'user'
AND p.name IN ('cards.read', 'collections.manage', 'decks.manage')
ON CONFLICT (role_id, permission_id) DO NOTHING;
`);
await client.query(`
INSERT INTO role_permissions (role_id, permission_id)
SELECT r.id, p.id
FROM roles r, permissions p
WHERE r.name = 'admin'
ON CONFLICT (role_id, permission_id) DO NOTHING;
`);
// Create indexes
await client.query(`
CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
CREATE INDEX IF NOT EXISTS idx_users_username ON users(username);
CREATE INDEX IF NOT EXISTS idx_user_roles_user_id ON user_roles(user_id);
`);
console.log('✅ User authentication schema setup completed!');
res.status(200).json({
success: true,
message: 'User authentication schema setup completed successfully'
});
} catch (error) {
console.error('Schema setup failed:', error);
res.status(500).json({
success: false,
error: 'Schema setup failed',
details: error.message
});
} finally {
client.release();
}
}