import { pgEnum, pgTable, boolean, timestamp, jsonb, text, uniqueIndex, foreignKey } from 'drizzle-orm/pg-core';
import { sql, relations, eq, and, gt } from 'drizzle-orm';
import { randomBytes } from 'crypto';
import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
import { useState, useCallback, useEffect } from 'react';

// src/auth/schema/enums.ts
var userRole = pgEnum("UserRole", ["USER", "ADMIN", "SUPER_ADMIN"]);
var user = pgTable(
  "User",
  {
    id: text().primaryKey().notNull(),
    email: text().notNull(),
    emailVerified: boolean().default(false).notNull(),
    username: text().notNull(),
    password: text(),
    name: text(),
    nickname: text(),
    image: text(),
    avatar: text(),
    role: userRole().default("USER").notNull(),
    preferences: jsonb(),
    createdAt: timestamp({ precision: 3, mode: "string" }).default(sql`CURRENT_TIMESTAMP`).notNull(),
    updatedAt: timestamp({ precision: 3, mode: "string" }).notNull(),
    twoFactorEnabled: boolean().default(false).notNull()
  },
  (table) => [
    uniqueIndex("User_email_key").using("btree", table.email.asc().nullsLast().op("text_ops")),
    uniqueIndex("User_username_key").using(
      "btree",
      table.username.asc().nullsLast().op("text_ops")
    )
  ]
);
var session = pgTable(
  "Session",
  {
    id: text().primaryKey().notNull(),
    userId: text().notNull(),
    token: text().notNull(),
    expiresAt: timestamp({ precision: 3, mode: "string" }).notNull(),
    ipAddress: text(),
    userAgent: text(),
    createdAt: timestamp({ precision: 3, mode: "string" }).default(sql`CURRENT_TIMESTAMP`).notNull(),
    updatedAt: timestamp({ precision: 3, mode: "string" }).default(sql`CURRENT_TIMESTAMP`).notNull()
  },
  (table) => [
    uniqueIndex("Session_token_key").using("btree", table.token.asc().nullsLast().op("text_ops")),
    foreignKey({
      columns: [table.userId],
      foreignColumns: [user.id],
      name: "Session_userId_fkey"
    }).onUpdate("cascade").onDelete("cascade")
  ]
);
var account = pgTable(
  "Account",
  {
    id: text().primaryKey().notNull(),
    accountId: text().notNull(),
    providerId: text().notNull(),
    // 提供商: github, google, wechat 等
    userId: text().notNull(),
    accessToken: text(),
    refreshToken: text(),
    idToken: text(),
    accessTokenExpiresAt: timestamp({ precision: 3, mode: "string" }),
    refreshTokenExpiresAt: timestamp({ precision: 3, mode: "string" }),
    scope: text(),
    password: text(),
    createdAt: timestamp({ precision: 3, mode: "string" }).default(sql`CURRENT_TIMESTAMP`).notNull(),
    updatedAt: timestamp({ precision: 3, mode: "string" }).notNull()
  },
  (table) => [
    uniqueIndex("Account_providerId_accountId_key").using(
      "btree",
      table.providerId.asc().nullsLast().op("text_ops"),
      table.accountId.asc().nullsLast().op("text_ops")
    ),
    foreignKey({
      columns: [table.userId],
      foreignColumns: [user.id],
      name: "Account_userId_fkey"
    }).onUpdate("cascade").onDelete("cascade")
  ]
);
var verifications = pgTable(
  "verifications",
  {
    id: text().primaryKey().notNull(),
    identifier: text().notNull(),
    // 邮箱或手机号
    value: text().notNull(),
    // 验证码
    expiresAt: timestamp({ precision: 3, mode: "string" }).notNull(),
    createdAt: timestamp({ precision: 3, mode: "string" }).default(sql`CURRENT_TIMESTAMP`).notNull()
  },
  (table) => [
    uniqueIndex("verifications_identifier_value_key").using(
      "btree",
      table.identifier.asc().nullsLast().op("text_ops"),
      table.value.asc().nullsLast().op("text_ops")
    )
  ]
);
var userRelations = relations(user, ({ many }) => ({
  sessions: many(session),
  accounts: many(account)
}));
var sessionRelations = relations(session, ({ one }) => ({
  user: one(user, {
    fields: [session.userId],
    references: [user.id]
  })
}));
var accountRelations = relations(account, ({ one }) => ({
  user: one(user, {
    fields: [account.userId],
    references: [user.id]
  })
}));
async function hashPassword(password, saltRounds = 12) {
  return bcrypt.hash(password, saltRounds);
}
async function verifyPassword(password, hashedPassword) {
  return bcrypt.compare(password, hashedPassword);
}
function generateToken(payload, secret, expiresIn = "7d") {
  return jwt.sign(payload, secret, { expiresIn });
}
function verifyJwtToken(token, secret) {
  return jwt.verify(token, secret);
}
function getTokenFromRequest(request) {
  const cookieHeader = request.headers.get("Cookie");
  if (cookieHeader) {
    const match = cookieHeader.match(/auth_token=([^;]+)/);
    if (match && match[1]) {
      return match[1];
    }
  }
  const authHeader = request.headers.get("Authorization");
  if (authHeader && authHeader.startsWith("Bearer ")) {
    const token = authHeader.substring(7);
    return token || null;
  }
  return null;
}

// src/auth/services/drizzle-auth-service.ts
var DrizzleAuthService = class {
  constructor(config) {
    this.config = {
      db: config.db,
      jwtSecret: config.jwtSecret,
      jwtExpiresIn: config.jwtExpiresIn || "7d",
      saltRounds: config.saltRounds || 12,
      checkSecretStrength: config.checkSecretStrength !== false
    };
    this.validateConfig();
  }
  /**
   * 验证配置
   */
  validateConfig() {
    if (!this.config.jwtSecret) {
      throw new Error(
        `JWT_SECRET is required. Please provide jwtSecret in config. You can generate a secure secret with: node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"`
      );
    }
    if (this.config.checkSecretStrength && process.env.NODE_ENV === "production" && this.config.jwtSecret.length < 32) {
      throw new Error(
        "JWT_SECRET is too short (" + this.config.jwtSecret.length + " chars, minimum 32 required in production)"
      );
    }
  }
  /**
   * 用户注册
   */
  async signUp(email, password, username, role = "USER") {
    try {
      const existingUser = await this.config.db.select().from(user).where(eq(user.email, email)).limit(1);
      if (existingUser.length > 0) {
        throw new Error("\u7528\u6237\u5DF2\u5B58\u5728");
      }
      const hashedPassword = await hashPassword(password, this.config.saltRounds);
      const [newUser] = await this.config.db.insert(user).values({
        id: randomBytes(16).toString("hex"),
        email,
        password: hashedPassword,
        username: username || email.split("@")[0],
        role,
        emailVerified: false,
        createdAt: (/* @__PURE__ */ new Date()).toISOString(),
        updatedAt: (/* @__PURE__ */ new Date()).toISOString()
      }).returning();
      const token = generateToken(
        {
          userId: newUser.id,
          email: newUser.email,
          role: newUser.role
        },
        this.config.jwtSecret,
        this.config.jwtExpiresIn
      );
      await this.createSession(newUser.id, token);
      return {
        user: {
          id: newUser.id,
          email: newUser.email,
          username: newUser.username,
          role: newUser.role
        },
        token
      };
    } catch (error) {
      throw error;
    }
  }
  /**
   * 用户登录
   */
  async signIn(email, password) {
    try {
      const [foundUser] = await this.config.db.select().from(user).where(eq(user.email, email)).limit(1);
      if (!foundUser) {
        throw new Error("\u90AE\u7BB1\u6216\u5BC6\u7801\u9519\u8BEF");
      }
      if (!foundUser.password) {
        throw new Error("\u7528\u6237\u5BC6\u7801\u672A\u8BBE\u7F6E");
      }
      const isPasswordValid = await verifyPassword(password, foundUser.password);
      if (!isPasswordValid) {
        throw new Error("\u90AE\u7BB1\u6216\u5BC6\u7801\u9519\u8BEF");
      }
      const token = generateToken(
        {
          userId: foundUser.id,
          email: foundUser.email,
          role: foundUser.role
        },
        this.config.jwtSecret,
        this.config.jwtExpiresIn
      );
      await this.createSession(foundUser.id, token);
      return {
        user: {
          id: foundUser.id,
          email: foundUser.email,
          username: foundUser.username,
          role: foundUser.role
        },
        token
      };
    } catch (error) {
      throw error;
    }
  }
  /**
   * 验证 Token
   */
  async verifyToken(token) {
    try {
      const decoded = verifyJwtToken(token, this.config.jwtSecret);
      const [foundSession] = await this.config.db.select().from(session).where(
        and(eq(session.token, token), gt(session.expiresAt, (/* @__PURE__ */ new Date()).toISOString()))
      ).limit(1);
      if (!foundSession) {
        throw new Error("\u4F1A\u8BDD\u65E0\u6548\u6216\u5DF2\u8FC7\u671F");
      }
      const [foundUser] = await this.config.db.select().from(user).where(eq(user.id, decoded.userId)).limit(1);
      if (!foundUser) {
        throw new Error("\u7528\u6237\u4E0D\u5B58\u5728");
      }
      return {
        user: {
          id: foundUser.id,
          email: foundUser.email,
          username: foundUser.username,
          role: foundUser.role
        },
        session: foundSession
      };
    } catch (error) {
      throw error;
    }
  }
  /**
   * 创建会话
   */
  async createSession(userId, token, ipAddress, userAgent) {
    const expiresAt = /* @__PURE__ */ new Date();
    expiresAt.setDate(expiresAt.getDate() + 7);
    await this.config.db.insert(session).values({
      id: randomBytes(16).toString("hex"),
      userId,
      token,
      expiresAt: expiresAt.toISOString(),
      ipAddress,
      userAgent,
      createdAt: (/* @__PURE__ */ new Date()).toISOString(),
      updatedAt: (/* @__PURE__ */ new Date()).toISOString()
    });
  }
  /**
   * 删除会话（登出）
   */
  async signOut(token) {
    try {
      await this.config.db.delete(session).where(eq(session.token, token));
      return { success: true };
    } catch (error) {
      throw error;
    }
  }
  /**
   * 获取会话
   */
  async getSession(token) {
    try {
      return await this.verifyToken(token);
    } catch (error) {
      return null;
    }
  }
  /**
   * 检查管理员权限
   */
  async requireAdmin(token) {
    const result = await this.verifyToken(token);
    if (!["ADMIN", "SUPER_ADMIN"].includes(result.user.role)) {
      throw new Error("\u9700\u8981\u7BA1\u7406\u5458\u6743\u9650");
    }
    return result;
  }
  /**
   * 检查超级管理员权限
   */
  async requireSuperAdmin(token) {
    const result = await this.verifyToken(token);
    if (result.user.role !== "SUPER_ADMIN") {
      throw new Error("\u9700\u8981\u8D85\u7EA7\u7BA1\u7406\u5458\u6743\u9650");
    }
    return result;
  }
  /**
   * 通过用户 ID 获取用户信息
   */
  async getUserById(userId) {
    try {
      const [foundUser] = await this.config.db.select().from(user).where(eq(user.id, userId)).limit(1);
      if (!foundUser) {
        return null;
      }
      return {
        id: foundUser.id,
        email: foundUser.email,
        username: foundUser.username,
        role: foundUser.role
      };
    } catch (error) {
      return null;
    }
  }
  /**
   * 通过邮箱获取用户信息
   */
  async getUserByEmail(email) {
    try {
      const [foundUser] = await this.config.db.select().from(user).where(eq(user.email, email)).limit(1);
      if (!foundUser) {
        return null;
      }
      return {
        id: foundUser.id,
        email: foundUser.email,
        username: foundUser.username,
        role: foundUser.role
      };
    } catch (error) {
      return null;
    }
  }
};

// src/auth/server.ts
async function validateApiAuth(request) {
  try {
    const token = getTokenFromRequest(request);
    if (!token) return null;
    const secret = process.env.JWT_SECRET || "your-secret-key";
    const payload = await verifyJwtToken(token, secret);
    if (!payload || !payload.userId) return null;
    return {
      id: payload.userId,
      email: payload.email,
      username: payload.username,
      role: payload.role
    };
  } catch (error) {
    console.error("API \u8EAB\u4EFD\u9A8C\u8BC1\u5931\u8D25:", error);
    return null;
  }
}
async function validateApiAuthNumeric(request) {
  const user2 = await validateApiAuth(request);
  if (!user2) return null;
  return {
    ...user2,
    id: parseInt(user2.id, 10)
  };
}

// src/auth/routes/login.ts
function addCorsHeaders(response, config, request) {
  if (!config.cors?.enabled) return response;
  const origin = request.headers.get("origin");
  const allowedOrigins = config.cors.origin;
  if (allowedOrigins) {
    if (typeof allowedOrigins === "string") {
      response.headers.set("Access-Control-Allow-Origin", allowedOrigins);
    } else if (Array.isArray(allowedOrigins) && origin && allowedOrigins.includes(origin)) {
      response.headers.set("Access-Control-Allow-Origin", origin);
    }
  } else {
    response.headers.set("Access-Control-Allow-Origin", origin || "*");
  }
  if (config.cors.credentials) {
    response.headers.set("Access-Control-Allow-Credentials", "true");
  }
  const methods = config.cors.methods || ["GET", "POST", "PUT", "DELETE", "OPTIONS"];
  response.headers.set("Access-Control-Allow-Methods", methods.join(", "));
  const headers = config.cors.allowedHeaders || ["Content-Type", "Authorization"];
  response.headers.set("Access-Control-Allow-Headers", headers.join(", "));
  return response;
}
function createLoginHandler(config) {
  return async (request) => {
    let requestBody = {};
    try {
      requestBody = await request.json();
      const { email, password } = requestBody;
      if (!email || !password) {
        const response2 = new Response(
          JSON.stringify({
            success: false,
            error: "\u90AE\u7BB1\u548C\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A"
          }),
          {
            status: 400,
            headers: { "Content-Type": "application/json" }
          }
        );
        return addCorsHeaders(response2, config, request);
      }
      const result = await config.authService.signIn(email, password);
      if (config.analytics) {
        try {
          await config.analytics.track("user_login_success", {
            userId: result.user.id,
            userRole: result.user.role,
            email: result.user.email,
            loginMethod: "email_password",
            timestamp: (/* @__PURE__ */ new Date()).toISOString()
          });
        } catch (analyticsError) {
          console.error("Failed to track login analytics:", analyticsError);
        }
      }
      const response = new Response(
        JSON.stringify({
          success: true,
          data: {
            user: result.user,
            token: result.token
          },
          message: "\u767B\u5F55\u6210\u529F"
        }),
        {
          status: 200,
          headers: { "Content-Type": "application/json" }
        }
      );
      if (config.cookieOptions) {
        const cookieOptions = {
          name: config.cookieOptions?.name || "auth_token",
          httpOnly: config.cookieOptions?.httpOnly !== false,
          secure: config.cookieOptions?.secure !== false && process.env.NODE_ENV === "production",
          sameSite: config.cookieOptions?.sameSite || "lax",
          maxAge: config.cookieOptions?.maxAge || 60 * 60 * 24 * 7,
          // 7天
          path: config.cookieOptions?.path || "/"
        };
        const cookieValue = cookieOptions.name + "=" + result.token + "; HttpOnly=" + cookieOptions.httpOnly + "; Secure=" + cookieOptions.secure + "; SameSite=" + cookieOptions.sameSite + "; Max-Age=" + cookieOptions.maxAge + "; Path=" + cookieOptions.path;
        response.headers.set("Set-Cookie", cookieValue);
      }
      return addCorsHeaders(response, config, request);
    } catch (error) {
      console.error("Login error:", error);
      if (config.analytics) {
        try {
          await config.analytics.track("user_login_failed", {
            errorMessage: error.message || "\u767B\u5F55\u5931\u8D25",
            email: requestBody.email,
            timestamp: (/* @__PURE__ */ new Date()).toISOString()
          });
        } catch (analyticsError) {
          console.error("Failed to track login failure analytics:", analyticsError);
        }
      }
      const response = new Response(
        JSON.stringify({
          success: false,
          error: error.message || "\u767B\u5F55\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u90AE\u7BB1\u548C\u5BC6\u7801"
        }),
        {
          status: 401,
          headers: { "Content-Type": "application/json" }
        }
      );
      return addCorsHeaders(response, config, request);
    }
  };
}
function createLoginOptionsHandler(config) {
  return async (request) => {
    const response = new Response(null, {
      status: 204,
      headers: {
        "Content-Length": "0"
      }
    });
    return addCorsHeaders(response, config, request);
  };
}

// src/auth/routes/register.ts
function addCorsHeaders2(response, config, request) {
  if (!config.cors?.enabled) return response;
  const origin = request.headers.get("origin");
  const allowedOrigins = config.cors.origin;
  if (allowedOrigins) {
    if (typeof allowedOrigins === "string") {
      response.headers.set("Access-Control-Allow-Origin", allowedOrigins);
    } else if (Array.isArray(allowedOrigins) && origin && allowedOrigins.includes(origin)) {
      response.headers.set("Access-Control-Allow-Origin", origin);
    }
  } else {
    response.headers.set("Access-Control-Allow-Origin", origin || "*");
  }
  if (config.cors.credentials) {
    response.headers.set("Access-Control-Allow-Credentials", "true");
  }
  const methods = config.cors.methods || ["GET", "POST", "PUT", "DELETE", "OPTIONS"];
  response.headers.set("Access-Control-Allow-Methods", methods.join(", "));
  const headers = config.cors.allowedHeaders || ["Content-Type", "Authorization"];
  response.headers.set("Access-Control-Allow-Headers", headers.join(", "));
  return response;
}
function createRegisterHandler(config) {
  return async (request) => {
    try {
      const { email, password, username } = await request.json();
      if (!email || !password) {
        const response2 = new Response(
          JSON.stringify({
            success: false,
            error: "\u90AE\u7BB1\u548C\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A"
          }),
          {
            status: 400,
            headers: { "Content-Type": "application/json" }
          }
        );
        return addCorsHeaders2(response2, config, request);
      }
      if (password.length < 6) {
        const response2 = new Response(
          JSON.stringify({
            success: false,
            error: "\u5BC6\u7801\u957F\u5EA6\u81F3\u5C11\u4E3A 6 \u4F4D"
          }),
          {
            status: 400,
            headers: { "Content-Type": "application/json" }
          }
        );
        return addCorsHeaders2(response2, config, request);
      }
      const result = await config.authService.signUp(
        email,
        password,
        username,
        config.defaultRole || "USER"
      );
      if (config.analytics) {
        try {
          await config.analytics.track("user_register_success", {
            userId: result.user.id,
            email: result.user.email,
            username: result.user.username,
            timestamp: (/* @__PURE__ */ new Date()).toISOString()
          });
        } catch (analyticsError) {
          console.error("Failed to track register analytics:", analyticsError);
        }
      }
      const response = new Response(
        JSON.stringify({
          success: true,
          data: {
            user: result.user,
            token: result.token
          },
          message: "\u6CE8\u518C\u6210\u529F"
        }),
        {
          status: 201,
          headers: { "Content-Type": "application/json" }
        }
      );
      if (config.cookieOptions) {
        const cookieOptions = {
          name: config.cookieOptions?.name || "auth_token",
          httpOnly: config.cookieOptions?.httpOnly !== false,
          secure: config.cookieOptions?.secure !== false && process.env.NODE_ENV === "production",
          sameSite: config.cookieOptions?.sameSite || "lax",
          maxAge: config.cookieOptions?.maxAge || 60 * 60 * 24 * 7,
          path: config.cookieOptions?.path || "/"
        };
        const cookieValue = cookieOptions.name + "=" + result.token + "; HttpOnly=" + cookieOptions.httpOnly + "; Secure=" + cookieOptions.secure + "; SameSite=" + cookieOptions.sameSite + "; Max-Age=" + cookieOptions.maxAge + "; Path=" + cookieOptions.path;
        response.headers.set("Set-Cookie", cookieValue);
      }
      return addCorsHeaders2(response, config, request);
    } catch (error) {
      console.error("Register error:", error);
      if (config.analytics) {
        try {
          await config.analytics.track("user_register_failed", {
            errorMessage: error.message || "\u6CE8\u518C\u5931\u8D25",
            timestamp: (/* @__PURE__ */ new Date()).toISOString()
          });
        } catch (analyticsError) {
          console.error("Failed to track register failure analytics:", analyticsError);
        }
      }
      const response = new Response(
        JSON.stringify({
          success: false,
          error: error.message || "\u6CE8\u518C\u5931\u8D25"
        }),
        {
          status: 400,
          headers: { "Content-Type": "application/json" }
        }
      );
      return addCorsHeaders2(response, config, request);
    }
  };
}
function createRegisterOptionsHandler(config) {
  return async (request) => {
    const response = new Response(null, {
      status: 204,
      headers: {
        "Content-Length": "0"
      }
    });
    if (config.cors?.enabled) {
      const origin = request.headers.get("origin");
      const allowedOrigins = config.cors.origin;
      if (allowedOrigins) {
        if (typeof allowedOrigins === "string") {
          response.headers.set("Access-Control-Allow-Origin", allowedOrigins);
        } else if (Array.isArray(allowedOrigins) && origin && allowedOrigins.includes(origin)) {
          response.headers.set("Access-Control-Allow-Origin", origin);
        }
      } else {
        response.headers.set("Access-Control-Allow-Origin", origin || "*");
      }
      if (config.cors.credentials) {
        response.headers.set("Access-Control-Allow-Credentials", "true");
      }
      const methods = config.cors.methods || ["GET", "POST", "PUT", "DELETE", "OPTIONS"];
      response.headers.set("Access-Control-Allow-Methods", methods.join(", "));
      const headers = config.cors.allowedHeaders || ["Content-Type", "Authorization"];
      response.headers.set("Access-Control-Allow-Headers", headers.join(", "));
    }
    return response;
  };
}

// src/auth/routes/me.ts
function addCorsHeaders3(response, config, request) {
  if (!config.cors?.enabled) return response;
  const origin = request.headers.get("origin");
  const allowedOrigins = config.cors.origin;
  if (allowedOrigins) {
    if (typeof allowedOrigins === "string") {
      response.headers.set("Access-Control-Allow-Origin", allowedOrigins);
    } else if (Array.isArray(allowedOrigins) && origin && allowedOrigins.includes(origin)) {
      response.headers.set("Access-Control-Allow-Origin", origin);
    }
  } else {
    response.headers.set("Access-Control-Allow-Origin", origin || "*");
  }
  if (config.cors.credentials) {
    response.headers.set("Access-Control-Allow-Credentials", "true");
  }
  const methods = config.cors.methods || ["GET", "POST", "PUT", "DELETE", "OPTIONS"];
  response.headers.set("Access-Control-Allow-Methods", methods.join(", "));
  const headers = config.cors.allowedHeaders || ["Content-Type", "Authorization"];
  response.headers.set("Access-Control-Allow-Headers", headers.join(", "));
  return response;
}
function createMeHandler(config) {
  return async (request) => {
    try {
      const token = getTokenFromRequest(request);
      if (!token) {
        const response2 = new Response(
          JSON.stringify({
            success: false,
            error: "\u672A\u63D0\u4F9B\u8BA4\u8BC1\u4EE4\u724C"
          }),
          {
            status: 401,
            headers: { "Content-Type": "application/json" }
          }
        );
        return addCorsHeaders3(response2, config, request);
      }
      const result = await config.authService.verifyToken(token);
      const response = new Response(
        JSON.stringify({
          success: true,
          data: result.user
        }),
        {
          status: 200,
          headers: { "Content-Type": "application/json" }
        }
      );
      return addCorsHeaders3(response, config, request);
    } catch (error) {
      console.error("Get user info error:", error);
      const response = new Response(
        JSON.stringify({
          success: false,
          error: "\u8BA4\u8BC1\u5931\u8D25"
        }),
        {
          status: 401,
          headers: { "Content-Type": "application/json" }
        }
      );
      return addCorsHeaders3(response, config, request);
    }
  };
}
function createMeOptionsHandler(config) {
  return async (request) => {
    const response = new Response(null, {
      status: 204,
      headers: {
        "Content-Length": "0"
      }
    });
    return addCorsHeaders3(response, config, request);
  };
}

// src/auth/routes/logout.ts
function addCorsHeaders4(response, config, request) {
  if (!config.cors?.enabled) return response;
  const origin = request.headers.get("origin");
  const allowedOrigins = config.cors.origin;
  if (allowedOrigins) {
    if (typeof allowedOrigins === "string") {
      response.headers.set("Access-Control-Allow-Origin", allowedOrigins);
    } else if (Array.isArray(allowedOrigins) && origin && allowedOrigins.includes(origin)) {
      response.headers.set("Access-Control-Allow-Origin", origin);
    }
  } else {
    response.headers.set("Access-Control-Allow-Origin", origin || "*");
  }
  if (config.cors.credentials) {
    response.headers.set("Access-Control-Allow-Credentials", "true");
  }
  const methods = config.cors.methods || ["GET", "POST", "PUT", "DELETE", "OPTIONS"];
  response.headers.set("Access-Control-Allow-Methods", methods.join(", "));
  const headers = config.cors.allowedHeaders || ["Content-Type", "Authorization"];
  response.headers.set("Access-Control-Allow-Headers", headers.join(", "));
  return response;
}
function createLogoutHandler(config) {
  return async (request) => {
    try {
      const token = getTokenFromRequest(request);
      if (!token) {
        const response2 = new Response(
          JSON.stringify({
            success: false,
            error: "\u672A\u63D0\u4F9B\u8BA4\u8BC1\u4EE4\u724C"
          }),
          {
            status: 401,
            headers: { "Content-Type": "application/json" }
          }
        );
        return addCorsHeaders4(response2, config, request);
      }
      await config.authService.signOut(token);
      if (config.analytics) {
        try {
          await config.analytics.track("user_logout", {
            timestamp: (/* @__PURE__ */ new Date()).toISOString()
          });
        } catch (analyticsError) {
          console.error("Failed to track logout analytics:", analyticsError);
        }
      }
      const response = new Response(
        JSON.stringify({
          success: true,
          message: "\u767B\u51FA\u6210\u529F"
        }),
        {
          status: 200,
          headers: { "Content-Type": "application/json" }
        }
      );
      response.headers.set(
        "Set-Cookie",
        "auth_token=; HttpOnly; Secure; SameSite=Lax; Max-Age=0; Path=/"
      );
      return addCorsHeaders4(response, config, request);
    } catch (error) {
      console.error("Logout error:", error);
      const response = new Response(
        JSON.stringify({
          success: false,
          error: "\u767B\u51FA\u5931\u8D25"
        }),
        {
          status: 500,
          headers: { "Content-Type": "application/json" }
        }
      );
      return addCorsHeaders4(response, config, request);
    }
  };
}
function createLogoutOptionsHandler(config) {
  return async (request) => {
    const response = new Response(null, {
      status: 204,
      headers: {
        "Content-Length": "0"
      }
    });
    return addCorsHeaders4(response, config, request);
  };
}

// src/auth/routes/defaults.ts
function createDefaultBaseConfig(authService, overrides) {
  return {
    authService,
    cors: {
      enabled: true,
      credentials: true,
      ...overrides?.cors
    },
    analytics: overrides?.analytics
  };
}
function createDefaultLoginConfig(authService, overrides) {
  return {
    authService,
    cors: {
      enabled: true,
      credentials: true,
      ...overrides?.cors
    },
    cookieOptions: {
      name: "auth_token",
      httpOnly: true,
      secure: process.env.NODE_ENV === "production",
      sameSite: "lax",
      maxAge: 60 * 60 * 24 * 7,
      // 7天
      path: "/",
      ...overrides?.cookieOptions
    },
    analytics: overrides?.analytics
  };
}
function createDefaultRegisterConfig(authService, overrides) {
  return {
    authService,
    defaultRole: overrides?.defaultRole || "USER",
    cors: {
      enabled: true,
      credentials: true,
      ...overrides?.cors
    },
    cookieOptions: overrides?.cookieOptions !== void 0 ? {
      name: "auth_token",
      httpOnly: true,
      secure: process.env.NODE_ENV === "production",
      sameSite: "lax",
      maxAge: 60 * 60 * 24 * 7,
      // 7天
      path: "/",
      ...overrides.cookieOptions
    } : void 0,
    analytics: overrides?.analytics,
    emailVerificationRequired: overrides?.emailVerificationRequired
  };
}

// src/auth/routes/analytics-adapter.ts
function createAnalyticsAdapter(analyticsService, options) {
  const config = {
    platform: options?.platform || "backend",
    appVersion: options?.appVersion || "1.0.0",
    sdkVersion: options?.sdkVersion || "1.0.0",
    deviceId: options?.deviceId || "server",
    generateId: options?.generateId || (() => {
      return Date.now() + "_" + Math.random().toString(36).substring(2, 15);
    })
  };
  return {
    track: async (eventName, properties) => {
      try {
        let eventType = "event";
        if (eventName.includes("login_success")) {
          eventType = "login";
        } else if (eventName.includes("register_success")) {
          eventType = "register";
        } else if (eventName.includes("logout")) {
          eventType = "logout";
        } else if (eventName.includes("failed") || eventName.includes("error")) {
          eventType = "error";
        }
        const event = {
          id: config.generateId(),
          eventType,
          eventName,
          timestamp: (/* @__PURE__ */ new Date()).toISOString(),
          priority: 1,
          userId: properties.userId || "anonymous",
          sessionId: properties.sessionId || "session_" + Date.now() + "_" + (properties.userId || "anonymous"),
          deviceId: config.deviceId,
          platform: config.platform,
          appVersion: config.appVersion,
          sdkVersion: config.sdkVersion,
          properties
        };
        await analyticsService.insertAnalyticsEvents([event]);
      } catch (error) {
        console.error("Failed to track analytics:", error);
      }
    }
  };
}

// src/auth/middleware/with-auth.ts
function createAuthMiddleware(config) {
  function withAuth(handler, level = "user") {
    return async (request, context = {}) => {
      if (level === "none") {
        return await handler(request, context);
      }
      try {
        const token = getTokenFromRequest(request);
        if (!token) {
          return new Response(
            JSON.stringify({
              success: false,
              error: "\u672A\u63D0\u4F9B\u8BA4\u8BC1\u4EE4\u724C"
            }),
            {
              status: 401,
              headers: { "Content-Type": "application/json" }
            }
          );
        }
        const result = await config.authService.verifyToken(token);
        if (level === "admin" || level === "super_admin") {
          if (!["ADMIN", "SUPER_ADMIN"].includes(result.user.role)) {
            return new Response(
              JSON.stringify({
                success: false,
                error: "\u9700\u8981\u7BA1\u7406\u5458\u6743\u9650"
              }),
              {
                status: 403,
                headers: { "Content-Type": "application/json" }
              }
            );
          }
        }
        if (level === "super_admin") {
          if (result.user.role !== "SUPER_ADMIN") {
            return new Response(
              JSON.stringify({
                success: false,
                error: "\u9700\u8981\u8D85\u7EA7\u7BA1\u7406\u5458\u6743\u9650"
              }),
              {
                status: 403,
                headers: { "Content-Type": "application/json" }
              }
            );
          }
        }
        context.user = result.user;
        context.session = result.session;
        return await handler(request, context);
      } catch (error) {
        console.error("Auth middleware error:", error);
        return new Response(
          JSON.stringify({
            success: false,
            error: "\u8BA4\u8BC1\u5931\u8D25"
          }),
          {
            status: 401,
            headers: { "Content-Type": "application/json" }
          }
        );
      }
    };
  }
  function requireAuth(handler) {
    return withAuth(handler, "user");
  }
  function requireAdmin(handler) {
    return withAuth(handler, "admin");
  }
  function requireSuperAdmin(handler) {
    return withAuth(handler, "super_admin");
  }
  return {
    withAuth,
    requireAuth,
    requireAdmin,
    requireSuperAdmin
  };
}
function useAuth(apiClient) {
  const [user2, setUser] = useState(null);
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const [loading, setLoading] = useState(false);
  const [checkingAuth, setCheckingAuth] = useState(true);
  const [error, setError] = useState(null);
  const checkAuthStatus = useCallback(async () => {
    try {
      setCheckingAuth(true);
      setError(null);
      const isAuth = await apiClient.isAuthenticated();
      if (isAuth) {
        const response = await apiClient.getCurrentUser();
        if (response.success && response.data) {
          setUser(response.data);
          setIsLoggedIn(true);
        } else {
          await apiClient.clearUserData();
          setUser(null);
          setIsLoggedIn(false);
        }
      } else {
        setUser(null);
        setIsLoggedIn(false);
      }
    } catch (err) {
      console.error("\u68C0\u67E5\u767B\u5F55\u72B6\u6001\u5931\u8D25:", err);
      setError(err instanceof Error ? err.message : "\u68C0\u67E5\u767B\u5F55\u72B6\u6001\u5931\u8D25");
      setUser(null);
      setIsLoggedIn(false);
    } finally {
      setCheckingAuth(false);
    }
  }, [apiClient]);
  const login = useCallback(
    async (email, password) => {
      setLoading(true);
      setError(null);
      try {
        const response = await apiClient.login(email, password);
        if (response.success && response.data) {
          setUser(response.data.user);
          setIsLoggedIn(true);
          return { success: true };
        } else {
          const errorMsg = response.error || "\u767B\u5F55\u5931\u8D25";
          setError(errorMsg);
          return { success: false, error: errorMsg };
        }
      } catch (err) {
        const errorMsg = err instanceof Error ? err.message : "\u767B\u5F55\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5";
        setError(errorMsg);
        return { success: false, error: errorMsg };
      } finally {
        setLoading(false);
      }
    },
    [apiClient]
  );
  const register = useCallback(
    async (email, password, username) => {
      setLoading(true);
      setError(null);
      try {
        const response = await apiClient.register(email, password, username);
        if (response.success && response.data) {
          setUser(response.data.user);
          setIsLoggedIn(true);
          return { success: true };
        } else {
          const errorMsg = response.error || "\u6CE8\u518C\u5931\u8D25";
          setError(errorMsg);
          return { success: false, error: errorMsg };
        }
      } catch (err) {
        const errorMsg = err instanceof Error ? err.message : "\u6CE8\u518C\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5";
        setError(errorMsg);
        return { success: false, error: errorMsg };
      } finally {
        setLoading(false);
      }
    },
    [apiClient]
  );
  const logout = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      await apiClient.logout();
      setUser(null);
      setIsLoggedIn(false);
    } catch (err) {
      console.error("\u767B\u51FA\u5931\u8D25:", err);
      setError(err instanceof Error ? err.message : "\u767B\u51FA\u5931\u8D25");
      setUser(null);
      setIsLoggedIn(false);
    } finally {
      setLoading(false);
    }
  }, [apiClient]);
  const clearError = useCallback(() => {
    setError(null);
  }, []);
  useEffect(() => {
    checkAuthStatus();
  }, [checkAuthStatus]);
  return {
    // 状态
    user: user2,
    isLoggedIn,
    loading,
    checkingAuth,
    error,
    // 操作方法
    login,
    register,
    logout,
    refresh: checkAuthStatus,
    clearError
  };
}
function useAuthForm(initialValues) {
  const [values, setValues] = useState(initialValues);
  const [errors, setErrors] = useState({});
  const [touched, setTouched] = useState({});
  const handleChange = useCallback(
    (field, value) => {
      setValues((prev) => ({ ...prev, [field]: value }));
      if (errors[field]) {
        setErrors((prev) => {
          const newErrors = { ...prev };
          delete newErrors[field];
          return newErrors;
        });
      }
    },
    [errors]
  );
  const handleBlur = useCallback((field) => {
    setTouched((prev) => ({ ...prev, [field]: true }));
  }, []);
  const validate = useCallback(
    (validationRules) => {
      const newErrors = {};
      Object.keys(validationRules).forEach((key) => {
        const field = key;
        const rule = validationRules[field];
        if (rule) {
          const error = rule(values[field]);
          if (error) {
            newErrors[field] = error;
          }
        }
      });
      setErrors(newErrors);
      return Object.keys(newErrors).length === 0;
    },
    [values]
  );
  const reset = useCallback(() => {
    setValues(initialValues);
    setErrors({});
    setTouched({});
  }, [initialValues]);
  return {
    values,
    errors,
    touched,
    handleChange,
    handleBlur,
    validate,
    reset,
    setValues,
    setErrors
  };
}

// src/auth/client/types.ts
var STORAGE_KEYS = {
  AUTH_TOKEN: "auth_token",
  USER_DATA: "user_data"
};
var API_ROUTES = {
  AUTH: {
    LOGIN: "/auth/login",
    REGISTER: "/auth/register",
    LOGOUT: "/auth/logout",
    ME: "/auth/me"
  }
};

// src/auth/client/base-api-client.ts
var BaseApiClient = class {
  constructor(storage, request, baseUrl) {
    this.storage = storage;
    this.request = request;
    this.baseUrl = baseUrl;
    this.token = null;
    this.user = null;
  }
  /**
   * 初始化 - 从存储中加载 token 和用户信息
   */
  async init() {
    try {
      this.token = await this.storage.getItem(STORAGE_KEYS.AUTH_TOKEN);
      const userData = await this.storage.getItem(STORAGE_KEYS.USER_DATA);
      if (userData) {
        this.user = JSON.parse(userData);
      }
    } catch (error) {
      console.error("Failed to load auth data:", error);
    }
  }
  /**
   * 设置认证 token
   */
  async setToken(token) {
    this.token = token;
    if (token) {
      await this.storage.setItem(STORAGE_KEYS.AUTH_TOKEN, token);
    } else {
      await this.storage.removeItem(STORAGE_KEYS.AUTH_TOKEN);
    }
  }
  /**
   * 设置用户信息
   */
  async setUser(user2) {
    this.user = user2;
    if (user2) {
      await this.storage.setItem(STORAGE_KEYS.USER_DATA, JSON.stringify(user2));
    } else {
      await this.storage.removeItem(STORAGE_KEYS.USER_DATA);
    }
  }
  /**
   * 获取当前 token
   */
  getToken() {
    return this.token;
  }
  /**
   * 获取当前用户
   */
  getUser() {
    return this.user;
  }
  /**
   * 检查是否已登录
   */
  async isAuthenticated() {
    return !!this.token;
  }
  /**
   * 清除用户数据
   */
  async clearUserData() {
    await this.storage.removeItem(STORAGE_KEYS.AUTH_TOKEN);
    await this.storage.removeItem(STORAGE_KEYS.USER_DATA);
    this.token = null;
    this.user = null;
  }
  /**
   * 发送请求的通用方法
   */
  async sendRequest(config) {
    try {
      const headers = {
        "Content-Type": "application/json",
        ...config.headers || {}
      };
      if (this.token) {
        headers["Authorization"] = "Bearer " + this.token;
      }
      const response = await this.request.request({
        ...config,
        url: this.baseUrl + config.url,
        headers
      });
      return response;
    } catch (error) {
      console.error("API request error:", error);
      return {
        success: false,
        error: error instanceof Error ? error.message : "\u7F51\u7EDC\u9519\u8BEF\uFF0C\u8BF7\u91CD\u8BD5"
      };
    }
  }
  // ==================== 认证相关 API ====================
  /**
   * 用户注册
   */
  async register(email, password, username) {
    const response = await this.sendRequest({
      url: API_ROUTES.AUTH.REGISTER,
      method: "POST",
      body: { email, password, username }
    });
    if (response.success && response.data) {
      await this.setToken(response.data.token);
      await this.setUser(response.data.user);
    }
    return response;
  }
  /**
   * 用户登录
   */
  async login(email, password) {
    const response = await this.sendRequest({
      url: API_ROUTES.AUTH.LOGIN,
      method: "POST",
      body: { email, password }
    });
    if (response.success && response.data) {
      await this.setToken(response.data.token);
      await this.setUser(response.data.user);
      if (typeof window !== "undefined") {
        window.dispatchEvent(
          new CustomEvent("user_login_success", {
            detail: {
              userId: response.data.user.id,
              email: response.data.user.email,
              role: response.data.user.role
            }
          })
        );
      }
    }
    return response;
  }
  /**
   * 用户退出登录
   */
  async logout() {
    await this.sendRequest({
      url: API_ROUTES.AUTH.LOGOUT,
      method: "POST"
    });
    await this.clearUserData();
  }
  /**
   * 获取当前用户信息
   */
  async getCurrentUser() {
    const response = await this.sendRequest({
      url: API_ROUTES.AUTH.ME,
      method: "GET"
    });
    if (response.success && response.data) {
      const userData = response.data.user || response.data;
      await this.setUser(userData);
      return {
        ...response,
        data: userData
      };
    }
    return response;
  }
  // ==================== 通用方法 ====================
  /**
   * 发送 GET 请求
   */
  async get(url, params) {
    return this.sendRequest({ url, method: "GET", params });
  }
  /**
   * 发送 POST 请求
   */
  async post(url, body) {
    return this.sendRequest({ url, method: "POST", body });
  }
  /**
   * 发送 PUT 请求
   */
  async put(url, body) {
    return this.sendRequest({ url, method: "PUT", body });
  }
  /**
   * 发送 DELETE 请求
   */
  async delete(url) {
    return this.sendRequest({ url, method: "DELETE" });
  }
};

export { API_ROUTES, BaseApiClient, DrizzleAuthService, STORAGE_KEYS, account, accountRelations, createAnalyticsAdapter, createAuthMiddleware, createDefaultBaseConfig, createDefaultLoginConfig, createDefaultRegisterConfig, createLoginHandler, createLoginOptionsHandler, createLogoutHandler, createLogoutOptionsHandler, createMeHandler, createMeOptionsHandler, createRegisterHandler, createRegisterOptionsHandler, generateToken, getTokenFromRequest, hashPassword, session, sessionRelations, useAuth, useAuthForm, user, userRelations, userRole, validateApiAuth, validateApiAuthNumeric, verifications, verifyJwtToken, verifyPassword };
//# sourceMappingURL=index.mjs.map
//# sourceMappingURL=index.mjs.map