"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
// backend/src/routes/share.ts
const express_1 = require("express");
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const crypto = __importStar(require("crypto"));
const auth_1 = require("../auth");
const config_1 = require("../config");
const router = (0, express_1.Router)();
const SHARES_FILE = path.join(config_1.DATA_DIR, 'session-shares.json');
function loadShares() {
    try {
        if (!fs.existsSync(SHARES_FILE))
            return [];
        return JSON.parse(fs.readFileSync(SHARES_FILE, 'utf-8'));
    }
    catch {
        return [];
    }
}
function saveShares(shares) {
    const tmp = SHARES_FILE + `.tmp.${process.pid}`;
    fs.writeFileSync(tmp, JSON.stringify(shares, null, 2), 'utf-8');
    fs.renameSync(tmp, SHARES_FILE);
}
// POST /api/sessions/:sessionId/share   body: { expiryDays?: number }
// Requires auth (manual JWT check since this route is mounted without authMiddleware)
router.post('/sessions/:sessionId/share', async (req, res) => {
    // Auth: localhost auto-auth or JWT
    if ((0, auth_1.isLocalRequest)(req)) {
        try {
            const config = (0, config_1.getConfig)();
            req.user = { username: config.username };
        }
        catch {
            req.user = { username: '__local_admin__' };
        }
    }
    else {
        const authHeader = req.headers['authorization'];
        const jwtToken = authHeader?.startsWith('Bearer ') ? authHeader.slice(7) : undefined;
        if (!jwtToken) {
            res.status(401).json({ error: 'Unauthorized' });
            return;
        }
        const user = (0, auth_1.verifyToken)(jwtToken);
        if (!user) {
            res.status(401).json({ error: 'Invalid token' });
            return;
        }
        req.user = user;
    }
    const { sessionId } = req.params;
    // Validate sessionId is a safe filename (no path traversal)
    if (!/^[A-Za-z0-9_-]+$/.test(sessionId)) {
        res.status(400).json({ error: 'Invalid session ID format' });
        return;
    }
    const { expiryDays } = req.body;
    // Find which project this session belongs to (scan projects accessible to caller)
    const projects = (0, config_1.getProjects)();
    let foundProjectId = null;
    for (const p of projects) {
        if (!(0, config_1.isProjectOwner)(p, req.user.username) && !(0, config_1.isAdminUser)(req.user.username))
            continue;
        const sessionFile = path.join(p.folderPath, '.ccweb', 'sessions', `${sessionId}.json`);
        if (fs.existsSync(sessionFile)) {
            foundProjectId = p.id;
            break;
        }
    }
    if (!foundProjectId) {
        res.status(404).json({ error: 'Session not found or access denied' });
        return;
    }
    const token = crypto.randomBytes(24).toString('base64url');
    const entry = {
        token,
        projectId: foundProjectId,
        sessionId,
        createdAt: new Date().toISOString(),
        ...(typeof expiryDays === 'number' && expiryDays > 0
            ? { expiresAt: new Date(Date.now() + expiryDays * 86400000).toISOString() }
            : {}),
    };
    const now = new Date();
    // Clean up expired entries and enforce max 500 shares
    let shares = loadShares().filter((s) => !s.expiresAt || new Date(s.expiresAt) >= now);
    shares.push(entry);
    if (shares.length > 500)
        shares = shares.slice(-500);
    saveShares(shares);
    res.json({ token, shareUrl: `/share/${token}` });
});
// GET /api/share/:token — NO AUTH REQUIRED — returns session data
router.get('/share/:token', (req, res) => {
    // Validate token format (base64url, 32 chars)
    const { token } = req.params;
    if (!token || !/^[A-Za-z0-9_-]{32}$/.test(token)) {
        res.status(404).json({ error: 'Share link not found' });
        return;
    }
    const shares = loadShares();
    const entry = shares.find((s) => s.token === token);
    if (!entry) {
        res.status(404).json({ error: 'Share link not found or expired' });
        return;
    }
    if (entry.expiresAt && new Date(entry.expiresAt) < new Date()) {
        res.status(410).json({ error: 'Share link has expired' });
        return;
    }
    const project = (0, config_1.getProject)(entry.projectId);
    if (!project) {
        res.status(404).json({ error: 'Project no longer exists' });
        return;
    }
    if (!/^[A-Za-z0-9_-]+$/.test(entry.sessionId)) {
        res.status(500).json({ error: 'Invalid stored session ID' });
        return;
    }
    const sessionFile = path.join(project.folderPath, '.ccweb', 'sessions', `${entry.sessionId}.json`);
    try {
        const raw = fs.readFileSync(sessionFile, 'utf-8');
        const session = JSON.parse(raw);
        res.json({ session, projectName: project.name });
    }
    catch {
        res.status(404).json({ error: 'Session data not found' });
    }
});
exports.default = router;
//# sourceMappingURL=share.js.map