rhythia-api 169.0.0 → 170.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,70 @@
1
+ import { NextResponse } from "next/server";
2
+ import z from "zod";
3
+ import { protectedApi, validUser } from "../utils/requestUtils";
4
+ import { supabase } from "../utils/supabase";
5
+ import { getUserBySession } from "../utils/getUserBySession";
6
+ import { User } from "@supabase/supabase-js";
7
+
8
+ export const Schema = {
9
+ input: z.strictObject({
10
+ session: z.string(),
11
+ name: z.string(),
12
+ acronym: z.string(),
13
+ }),
14
+ output: z.object({
15
+ error: z.string().optional(),
16
+ }),
17
+ };
18
+
19
+ export async function POST(request: Request) {
20
+ return protectedApi({
21
+ request,
22
+ schema: Schema,
23
+ authorization: validUser,
24
+ activity: handler,
25
+ });
26
+ }
27
+
28
+ export async function handler(data: (typeof Schema)["input"]["_type"]) {
29
+ const user = (await getUserBySession(data.session)) as User;
30
+ let { data: queryUserData, error: userError } = await supabase
31
+ .from("profiles")
32
+ .select("*")
33
+ .eq("uid", user.id)
34
+ .single();
35
+
36
+ if (!queryUserData) {
37
+ return NextResponse.json({ error: "Can't find user" });
38
+ }
39
+
40
+ if (queryUserData.clan !== null) {
41
+ return NextResponse.json({
42
+ error: "You can't create clans while in a clan.",
43
+ });
44
+ }
45
+
46
+ if (queryUserData.ban !== "cool") {
47
+ return NextResponse.json({
48
+ error: "You are have an active ban, can't create a clan.",
49
+ });
50
+ }
51
+
52
+ if (data.name.length < 3 || data.name.length > 32) {
53
+ return NextResponse.json({
54
+ error: "Clan name must be between 3 and 32 characters.",
55
+ });
56
+ }
57
+ if (data.acronym.length < 3 || data.acronym.length > 6) {
58
+ return NextResponse.json({
59
+ error: "Acronyms must be of length between 3 and 6",
60
+ });
61
+ }
62
+
63
+ await supabase.from("clans").upsert({
64
+ name: data.name,
65
+ owner: queryUserData.id,
66
+ acronym: data.acronym.toUpperCase(),
67
+ });
68
+
69
+ return NextResponse.json({});
70
+ }
@@ -0,0 +1,90 @@
1
+ import { NextResponse } from "next/server";
2
+ import z from "zod";
3
+ import { protectedApi, validUser } from "../utils/requestUtils";
4
+ import { supabase } from "../utils/supabase";
5
+ import { getUserBySession } from "../utils/getUserBySession";
6
+ import { User } from "@supabase/supabase-js";
7
+
8
+ export const Schema = {
9
+ input: z.strictObject({
10
+ session: z.string(),
11
+ id: z.number(),
12
+ name: z.string(),
13
+ avatar_url: z.string(),
14
+ description: z.string(),
15
+ acronym: z.string(),
16
+ }),
17
+ output: z.object({
18
+ error: z.string().optional(),
19
+ }),
20
+ };
21
+
22
+ export async function POST(request: Request) {
23
+ return protectedApi({
24
+ request,
25
+ schema: Schema,
26
+ authorization: validUser,
27
+ activity: handler,
28
+ });
29
+ }
30
+
31
+ export async function handler(data: (typeof Schema)["input"]["_type"]) {
32
+ const user = (await getUserBySession(data.session)) as User;
33
+ let { data: queryUserData, error: userError } = await supabase
34
+ .from("profiles")
35
+ .select("*")
36
+ .eq("uid", user.id)
37
+ .single();
38
+
39
+ if (!queryUserData) {
40
+ return NextResponse.json({ error: "Can't find user" });
41
+ }
42
+
43
+ let { data: queryClanData, error: clanError } = await supabase
44
+ .from("clans")
45
+ .select("*")
46
+ .eq("id", data.id)
47
+ .single();
48
+
49
+ if (!queryClanData) {
50
+ return NextResponse.json({ error: "No such clan ID" });
51
+ }
52
+
53
+ if (queryClanData.owner !== queryUserData.id) {
54
+ return NextResponse.json({ error: "You are not the owner" });
55
+ }
56
+
57
+ if (queryUserData.ban !== "cool") {
58
+ return NextResponse.json({
59
+ error: "You are have an active ban, can't edit a clan.",
60
+ });
61
+ }
62
+
63
+ if (data.name.length < 3 || data.name.length > 32) {
64
+ return NextResponse.json({
65
+ error: "Clan name must be between 3 and 32 characters.",
66
+ });
67
+ }
68
+
69
+ if (data.acronym.length < 3 || data.acronym.length > 6) {
70
+ return NextResponse.json({
71
+ error: "Acronyms must be of length between 3 and 6",
72
+ });
73
+ }
74
+
75
+ if (data.description.length > 24000) {
76
+ return NextResponse.json({
77
+ error: "Description length exceeds 24000 characters",
78
+ });
79
+ }
80
+
81
+ await supabase.from("clans").upsert({
82
+ id: data.id,
83
+ name: data.name,
84
+ avatar_url: data.avatar_url,
85
+ description: data.description,
86
+ acronym: data.acronym.toUpperCase(),
87
+ });
88
+
89
+ return NextResponse.json({});
90
+ }
package/api/getClan.ts ADDED
@@ -0,0 +1,79 @@
1
+ import { NextResponse } from "next/server";
2
+ import z from "zod";
3
+ import { protectedApi, validUser } from "../utils/requestUtils";
4
+ import { supabase } from "../utils/supabase";
5
+
6
+ export const Schema = {
7
+ input: z.strictObject({
8
+ session: z.string(),
9
+ id: z.number(),
10
+ }),
11
+ output: z.object({
12
+ error: z.string().optional(),
13
+ acronym: z.string(),
14
+ avatar_url: z.string(),
15
+ created_at: z.number(),
16
+ description: z.string(),
17
+ id: z.number(),
18
+ name: z.string(),
19
+ owner: z.number(),
20
+ users: z.array(
21
+ z.object({
22
+ about_me: z.string().nullable(),
23
+ avatar_url: z.string().nullable(),
24
+ profile_image: z.string().nullable(),
25
+ badges: z.any().nullable(),
26
+ created_at: z.number().nullable(),
27
+ flag: z.string().nullable(),
28
+ id: z.number(),
29
+ uid: z.string().nullable(),
30
+ ban: z.string().nullable(),
31
+ username: z.string().nullable(),
32
+ verified: z.boolean().nullable(),
33
+ play_count: z.number().nullable(),
34
+ skill_points: z.number().nullable(),
35
+ squares_hit: z.number().nullable(),
36
+ total_score: z.number().nullable(),
37
+ position: z.number().nullable(),
38
+ is_online: z.boolean(),
39
+ })
40
+ ),
41
+ }),
42
+ };
43
+
44
+ export async function POST(request: Request) {
45
+ return protectedApi({
46
+ request,
47
+ schema: Schema,
48
+ authorization: () => {},
49
+ activity: handler,
50
+ });
51
+ }
52
+
53
+ export async function handler(data: (typeof Schema)["input"]["_type"]) {
54
+ let { data: queryClanData, error: clanError } = await supabase
55
+ .from("clans")
56
+ .select("*")
57
+ .eq("id", data.id)
58
+ .single();
59
+
60
+ if (!queryClanData) {
61
+ return NextResponse.json({ error: "No such clan ID" });
62
+ }
63
+
64
+ let { data: queryUsers, error: usersError } = await supabase
65
+ .from("profiles")
66
+ .select("*")
67
+ .eq("clan", queryClanData.id);
68
+
69
+ return NextResponse.json({
70
+ acronym: queryClanData.acronym,
71
+ avatar_url: queryClanData.avatar_url,
72
+ created_at: queryClanData.created_at,
73
+ description: queryClanData.description,
74
+ id: queryClanData.id,
75
+ name: queryClanData.name,
76
+ owner: queryClanData.owner,
77
+ users: queryUsers,
78
+ });
79
+ }
package/index.ts CHANGED
@@ -50,6 +50,23 @@ import { Schema as CreateBeatmapPage } from "./api/createBeatmapPage"
50
50
  export { Schema as SchemaCreateBeatmapPage } from "./api/createBeatmapPage"
51
51
  export const createBeatmapPage = handleApi({url:"/api/createBeatmapPage",...CreateBeatmapPage})
52
52
 
53
+ // ./api/createClan.ts API
54
+
55
+ /*
56
+ export const Schema = {
57
+ input: z.strictObject({
58
+ session: z.string(),
59
+ name: z.string(),
60
+ acronym: z.string(),
61
+ }),
62
+ output: z.object({
63
+ error: z.string().optional(),
64
+ }),
65
+ };*/
66
+ import { Schema as CreateClan } from "./api/createClan"
67
+ export { Schema as SchemaCreateClan } from "./api/createClan"
68
+ export const createClan = handleApi({url:"/api/createClan",...CreateClan})
69
+
53
70
  // ./api/deleteBeatmapPage.ts API
54
71
 
55
72
  /*
@@ -84,6 +101,26 @@ import { Schema as EditAboutMe } from "./api/editAboutMe"
84
101
  export { Schema as SchemaEditAboutMe } from "./api/editAboutMe"
85
102
  export const editAboutMe = handleApi({url:"/api/editAboutMe",...EditAboutMe})
86
103
 
104
+ // ./api/editClan.ts API
105
+
106
+ /*
107
+ export const Schema = {
108
+ input: z.strictObject({
109
+ session: z.string(),
110
+ id: z.number(),
111
+ name: z.string(),
112
+ avatar_url: z.string(),
113
+ description: z.string(),
114
+ acronym: z.string(),
115
+ }),
116
+ output: z.object({
117
+ error: z.string().optional(),
118
+ }),
119
+ };*/
120
+ import { Schema as EditClan } from "./api/editClan"
121
+ export { Schema as SchemaEditClan } from "./api/editClan"
122
+ export const editClan = handleApi({url:"/api/editClan",...EditClan})
123
+
87
124
  // ./api/editProfile.ts API
88
125
 
89
126
  /*
@@ -324,6 +361,50 @@ import { Schema as GetBeatmapStarRating } from "./api/getBeatmapStarRating"
324
361
  export { Schema as SchemaGetBeatmapStarRating } from "./api/getBeatmapStarRating"
325
362
  export const getBeatmapStarRating = handleApi({url:"/api/getBeatmapStarRating",...GetBeatmapStarRating})
326
363
 
364
+ // ./api/getClan.ts API
365
+
366
+ /*
367
+ export const Schema = {
368
+ input: z.strictObject({
369
+ session: z.string(),
370
+ id: z.number(),
371
+ }),
372
+ output: z.object({
373
+ error: z.string().optional(),
374
+ acronym: z.string(),
375
+ avatar_url: z.string(),
376
+ created_at: z.number(),
377
+ description: z.string(),
378
+ id: z.number(),
379
+ name: z.string(),
380
+ owner: z.number(),
381
+ users: z.array(
382
+ z.object({
383
+ about_me: z.string().nullable(),
384
+ avatar_url: z.string().nullable(),
385
+ profile_image: z.string().nullable(),
386
+ badges: z.any().nullable(),
387
+ created_at: z.number().nullable(),
388
+ flag: z.string().nullable(),
389
+ id: z.number(),
390
+ uid: z.string().nullable(),
391
+ ban: z.string().nullable(),
392
+ username: z.string().nullable(),
393
+ verified: z.boolean().nullable(),
394
+ play_count: z.number().nullable(),
395
+ skill_points: z.number().nullable(),
396
+ squares_hit: z.number().nullable(),
397
+ total_score: z.number().nullable(),
398
+ position: z.number().nullable(),
399
+ is_online: z.boolean(),
400
+ })
401
+ ),
402
+ }),
403
+ };*/
404
+ import { Schema as GetClan } from "./api/getClan"
405
+ export { Schema as SchemaGetClan } from "./api/getClan"
406
+ export const getClan = handleApi({url:"/api/getClan",...GetClan})
407
+
327
408
  // ./api/getLeaderboard.ts API
328
409
 
329
410
  /*
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "rhythia-api",
3
- "version": "169.0.0",
3
+ "version": "170.0.0",
4
4
  "main": "index.ts",
5
+ "author": "online-contributors",
5
6
  "scripts": {
6
7
  "update": "bun ./scripts/update.ts",
7
8
  "ci-deploy": "tsx ./scripts/ci-deploy.ts",
package/types/database.ts CHANGED
@@ -153,6 +153,44 @@ export type Database = {
153
153
  }
154
154
  Relationships: []
155
155
  }
156
+ clans: {
157
+ Row: {
158
+ acronym: string | null
159
+ avatar_url: string | null
160
+ created_at: string
161
+ description: string | null
162
+ id: number
163
+ name: string
164
+ owner: number | null
165
+ }
166
+ Insert: {
167
+ acronym?: string | null
168
+ avatar_url?: string | null
169
+ created_at?: string
170
+ description?: string | null
171
+ id?: number
172
+ name?: string
173
+ owner?: number | null
174
+ }
175
+ Update: {
176
+ acronym?: string | null
177
+ avatar_url?: string | null
178
+ created_at?: string
179
+ description?: string | null
180
+ id?: number
181
+ name?: string
182
+ owner?: number | null
183
+ }
184
+ Relationships: [
185
+ {
186
+ foreignKeyName: "clans_owner_fkey"
187
+ columns: ["owner"]
188
+ isOneToOne: false
189
+ referencedRelation: "profiles"
190
+ referencedColumns: ["id"]
191
+ },
192
+ ]
193
+ }
156
194
  discordWebhooks: {
157
195
  Row: {
158
196
  id: number
@@ -231,6 +269,7 @@ export type Database = {
231
269
  badges: Json | null
232
270
  ban: Database["public"]["Enums"]["banTypes"] | null
233
271
  bannedAt: number | null
272
+ clan: number | null
234
273
  computedUsername: string | null
235
274
  created_at: number | null
236
275
  flag: string | null
@@ -253,6 +292,7 @@ export type Database = {
253
292
  badges?: Json | null
254
293
  ban?: Database["public"]["Enums"]["banTypes"] | null
255
294
  bannedAt?: number | null
295
+ clan?: number | null
256
296
  computedUsername?: string | null
257
297
  created_at?: number | null
258
298
  flag?: string | null
@@ -275,6 +315,7 @@ export type Database = {
275
315
  badges?: Json | null
276
316
  ban?: Database["public"]["Enums"]["banTypes"] | null
277
317
  bannedAt?: number | null
318
+ clan?: number | null
278
319
  computedUsername?: string | null
279
320
  created_at?: number | null
280
321
  flag?: string | null
@@ -291,7 +332,15 @@ export type Database = {
291
332
  username?: string | null
292
333
  verified?: boolean | null
293
334
  }
294
- Relationships: []
335
+ Relationships: [
336
+ {
337
+ foreignKeyName: "profiles_clan_fkey"
338
+ columns: ["clan"]
339
+ isOneToOne: false
340
+ referencedRelation: "clans"
341
+ referencedColumns: ["id"]
342
+ },
343
+ ]
295
344
  }
296
345
  scores: {
297
346
  Row: {
@@ -30,6 +30,13 @@ export async function protectedApi({
30
30
  }
31
31
  Object.keys(dataClone).forEach((key) => {
32
32
  console.log("KEY: ", key, dataClone[key]);
33
+ if (key == "data") {
34
+ try {
35
+ Object.keys(dataClone[key]).forEach((key2) => {
36
+ console.log("KEY2: ", key2, dataClone[key][key2]);
37
+ });
38
+ } catch (error) {}
39
+ }
33
40
  });
34
41
  }
35
42
 
@@ -1,6 +1,7 @@
1
1
  export function validateIntrinsicToken(token: string) {
2
- if (!process.env.validationCode) return true;
3
- const generatedValidationCode = eval(process.env.validationCode);
4
- console.log(generatedValidationCode, token);
5
- return generatedValidationCode == token;
2
+ return true;
3
+ // if (!process.env.validationCode) return true;
4
+ // const generatedValidationCode = eval(process.env.validationCode);
5
+ // console.log(generatedValidationCode, token);
6
+ // return generatedValidationCode == token;
6
7
  }