sare26 commited on
Commit
99e3619
·
verified ·
1 Parent(s): 49787cf

Update artifacts/api-server/src/routes/me/index.ts

Browse files
artifacts/api-server/src/routes/me/index.ts CHANGED
@@ -1,7 +1,6 @@
1
  import { Router, type Request, type Response } from "express";
2
  import { db, subscriptionsTable, usersTable } from "@workspace/db";
3
  import { eq } from "drizzle-orm";
4
- import { stackServerApp } from "@stackframe/stack";
5
 
6
  const router = Router();
7
 
@@ -9,173 +8,39 @@ function buildTrialEnd(): Date {
9
  return new Date(Date.now() + 30 * 24 * 60 * 60 * 1000);
10
  }
11
 
12
- function getClientIp(req: Request): string | null {
13
- const forwarded = req.headers["x-forwarded-for"];
14
- if (forwarded) {
15
- const ip = Array.isArray(forwarded) ? forwarded[0] : forwarded.split(",")[0];
16
- return ip?.trim() ?? null;
17
- }
18
- return req.socket?.remoteAddress ?? null;
19
- }
20
-
21
- // ✅ بديل requireAuth من Clerk - يستخدم Stack Auth
22
- async function requireAuth(req: Request, res: Response): Promise<{ userId: string; userEmail: string | null } | null> {
23
- const authHeader = req.headers.authorization;
24
- if (!authHeader?.startsWith("Bearer ")) {
25
- res.status(401).json({ error: "Unauthorized" });
26
- return null;
27
- }
28
-
29
- const token = authHeader.split(" ")[1];
30
-
31
- try {
32
- const user = await stackServerApp.getUser(token);
33
- if (!user) {
34
- res.status(401).json({ error: "Invalid token" });
35
- return null;
36
- }
37
- return {
38
- userId: user.id,
39
- userEmail: user.primaryEmail ?? null,
40
- };
41
- } catch {
42
- res.status(401).json({ error: "Invalid token" });
43
- return null;
44
- }
45
- }
46
-
47
  router.get("/", async (req: Request, res: Response) => {
48
- const auth = await requireAuth(req, res);
49
- if (!auth) return;
50
-
51
- const { userId, userEmail } = auth;
52
- const clientIp = getClientIp(req);
53
  const now = new Date();
 
 
 
 
54
 
55
- // 👑 استثناء حساب المالك الماستر
56
  if (userEmail && userEmail.toLowerCase() === "saresare2555@hotmail.com") {
57
- const [ownerSub] = await db
58
- .select()
59
- .from(subscriptionsTable)
60
- .where(eq(subscriptionsTable.userId, userId));
61
-
62
- if (ownerSub && ownerSub.status === "trial_expired") {
63
- res.set("Cache-Control", "private, max-age=60");
64
- return res.json({
65
- userId,
66
- email: userEmail,
67
- subscription: {
68
- status: "trial_expired",
69
- trialEnd: ownerSub.trialEnd?.toISOString() ?? null,
70
- currentPeriodEnd: null,
71
- paypalSubscriptionId: null,
72
- hasAccess: false,
73
- },
74
- });
75
- }
76
-
77
- res.set("Cache-Control", "private, max-age=60");
78
  return res.json({
79
- userId,
80
- email: userEmail,
81
- subscription: {
82
- status: "active",
83
- trialEnd: null,
84
- currentPeriodEnd: null,
85
- paypalSubscriptionId: null,
86
- hasAccess: true,
87
- },
88
  });
89
  }
90
 
91
  try {
92
- await db
93
- .insert(usersTable)
94
- .values({
95
- id: userId,
96
- email: userEmail ? userEmail.toLowerCase() : null,
97
- ipAddress: clientIp,
98
- lastSeenAt: now,
99
- isBanned: false
100
- })
101
- .onConflictDoUpdate({
102
- target: usersTable.id,
103
- set: {
104
- email: userEmail ? userEmail.toLowerCase() : null,
105
- ipAddress: clientIp,
106
- lastSeenAt: now,
107
- },
108
- });
109
-
110
- let [sub] = await db
111
- .select()
112
- .from(subscriptionsTable)
113
- .where(eq(subscriptionsTable.userId, userId));
114
 
 
115
  if (!sub) {
116
  const trialEnd = buildTrialEnd();
117
- const [created] = await db
118
- .insert(subscriptionsTable)
119
- .values({ userId, status: "trialing", trialEnd, updatedAt: now })
120
- .returning();
121
  sub = created;
122
  }
123
 
124
- const [userCheck] = await db
125
- .select({ isBanned: usersTable.isBanned })
126
- .from(usersTable)
127
- .where(eq(usersTable.id, userId));
128
-
129
- if (userCheck?.isBanned) {
130
- return res.status(403).json({ error: "banned", message: "تم إيقاف هذا الحساب." });
131
- }
132
-
133
  let status: string = sub?.status ?? "none";
134
- let hasAccess = false;
135
-
136
- if (sub) {
137
- if (status === "trialing") {
138
- if (sub.trialEnd && sub.trialEnd > now) {
139
- hasAccess = true;
140
- } else if (sub.trialEnd && sub.trialEnd <= now) {
141
- status = "trial_expired";
142
- }
143
- } else if (status === "trial_expired" || status === "expired") {
144
- hasAccess = false;
145
- } else if (status === "active") {
146
- if (!sub.currentPeriodEnd || sub.currentPeriodEnd > now) {
147
- hasAccess = true;
148
- }
149
- }
150
- }
151
-
152
- res.set("Cache-Control", "private, max-age=60");
153
- return res.json({
154
- userId,
155
- email: userEmail,
156
- subscription: {
157
- status,
158
- trialEnd: sub?.trialEnd?.toISOString() ?? null,
159
- currentPeriodEnd: sub?.currentPeriodEnd?.toISOString() ?? null,
160
- paypalSubscriptionId: sub?.paypalSubscriptionId ?? null,
161
- hasAccess,
162
- },
163
- });
164
 
 
165
  } catch (error) {
166
- console.error("[me] Error:", error);
167
- res.set("Cache-Control", "private, max-age=60");
168
- return res.json({
169
- userId,
170
- email: userEmail,
171
- subscription: {
172
- status: "trialing",
173
- trialEnd: buildTrialEnd().toISOString(),
174
- currentPeriodEnd: null,
175
- paypalSubscriptionId: null,
176
- hasAccess: true,
177
- },
178
- });
179
  }
180
  });
181
 
 
1
  import { Router, type Request, type Response } from "express";
2
  import { db, subscriptionsTable, usersTable } from "@workspace/db";
3
  import { eq } from "drizzle-orm";
 
4
 
5
  const router = Router();
6
 
 
8
  return new Date(Date.now() + 30 * 24 * 60 * 60 * 1000);
9
  }
10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  router.get("/", async (req: Request, res: Response) => {
 
 
 
 
 
12
  const now = new Date();
13
+
14
+ // ✅ استخراج userId من headers (Kinde يمرره)
15
+ const userId = req.headers["x-user-id"] as string || "demo-user";
16
+ const userEmail = req.headers["x-user-email"] as string || null;
17
 
18
+ // 👑 استثناء حساب المالك
19
  if (userEmail && userEmail.toLowerCase() === "saresare2555@hotmail.com") {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  return res.json({
21
+ userId, email: userEmail,
22
+ subscription: { status: "active", trialEnd: null, currentPeriodEnd: null, paypalSubscriptionId: null, hasAccess: true },
 
 
 
 
 
 
 
23
  });
24
  }
25
 
26
  try {
27
+ await db.insert(usersTable).values({ id: userId, email: userEmail?.toLowerCase() ?? null, isBanned: false, lastSeenAt: now })
28
+ .onConflictDoUpdate({ target: usersTable.id, set: { email: userEmail?.toLowerCase() ?? null, lastSeenAt: now } });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
+ let [sub] = await db.select().from(subscriptionsTable).where(eq(subscriptionsTable.userId, userId));
31
  if (!sub) {
32
  const trialEnd = buildTrialEnd();
33
+ const [created] = await db.insert(subscriptionsTable).values({ userId, status: "trialing", trialEnd, updatedAt: now }).returning();
 
 
 
34
  sub = created;
35
  }
36
 
 
 
 
 
 
 
 
 
 
37
  let status: string = sub?.status ?? "none";
38
+ let hasAccess = status === "trialing" && sub?.trialEnd && sub.trialEnd > now ? true
39
+ : status === "active" ? true : false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
+ return res.json({ userId, email: userEmail, subscription: { status, trialEnd: sub?.trialEnd?.toISOString() ?? null, currentPeriodEnd: sub?.currentPeriodEnd?.toISOString() ?? null, paypalSubscriptionId: null, hasAccess } });
42
  } catch (error) {
43
+ return res.json({ userId, email: userEmail, subscription: { status: "trialing", trialEnd: buildTrialEnd().toISOString(), currentPeriodEnd: null, paypalSubscriptionId: null, hasAccess: true } });
 
 
 
 
 
 
 
 
 
 
 
 
44
  }
45
  });
46