File size: 3,144 Bytes
eeb9404
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/**
 * Registration API Route
 *
 * Creates a new user account in the system database.
 */

import { NextRequest, NextResponse } from 'next/server';
import { createSession } from '@/lib/auth/session';
import { createUser, getUserByEmail, getUserCount, createWorkspace, setDefaultWorkspace, updateWorkspace } from '@/lib/auth/system-database';
import { hashPassword } from '@/lib/auth/passwords';
import { logger } from '@/lib/utils';
import { getSystemDatabase } from '@/lib/auth/system-database';

export async function POST(request: NextRequest) {
  try {
    const userCount = getUserCount();
    const isFirstUser = userCount === 0;
    const registrationMode = process.env.REGISTRATION_MODE || 'closed';

    // Allow registration if: open mode, OR no users exist yet (initial setup)
    if (registrationMode !== 'open' && !isFirstUser) {
      return NextResponse.json(
        { error: 'Registration is not available on this instance' },
        { status: 403 }
      );
    }

    const body = await request.json();
    const { email, password, displayName } = body;

    if (!email || !password) {
      return NextResponse.json({ error: 'Email and password required' }, { status: 400 });
    }

    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(email)) {
      return NextResponse.json({ error: 'Invalid email format' }, { status: 400 });
    }

    if (password.length < 8) {
      return NextResponse.json({ error: 'Password must be at least 8 characters' }, { status: 400 });
    }

    const existing = getUserByEmail(email);
    if (existing) {
      return NextResponse.json({ error: 'Email already registered' }, { status: 409 });
    }

    const passwordHash = await hashPassword(password);
    const userId = createUser(email, passwordHash, displayName);

    // First user becomes admin
    if (isFirstUser) {
      const db = getSystemDatabase();
      db.prepare("UPDATE users SET is_admin = 1, updated_at = datetime('now') WHERE id = ?").run(userId);
    }

    // Create default workspace
    const workspaceName = displayName ? `${displayName}'s Workspace` : 'My Workspace';
    const workspaceId = createWorkspace(workspaceName, userId);

    // First user gets unlimited workspace
    if (isFirstUser) {
      updateWorkspace(workspaceId, {
        max_projects: 9999,
        max_deployments: 9999,
        max_storage_mb: 99999,
      });
    }

    setDefaultWorkspace(userId, workspaceId);

    const token = await createSession(userId, email, isFirstUser);
    const response = NextResponse.json({ success: true, userId, defaultWorkspaceId: workspaceId, defaultWorkspaceName: workspaceName });
    response.cookies.set('osw_session', token, {
      httpOnly: true,
      secure: process.env.SECURE_COOKIES !== 'false' && process.env.NODE_ENV === 'production',
      sameSite: 'lax',
      maxAge: 24 * 60 * 60,
      path: '/',
    });
    return response;
  } catch (error) {
    logger.error('[API /api/auth/register] Error:', error);
    return NextResponse.json(
      { error: error instanceof Error ? error.message : 'Registration failed' },
      { status: 500 }
    );
  }
}