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.
- package/api/createClan.ts +70 -0
- package/api/editClan.ts +90 -0
- package/api/getClan.ts +79 -0
- package/index.ts +81 -0
- package/package.json +2 -1
- package/types/database.ts +50 -1
- package/utils/requestUtils.ts +7 -0
- package/utils/validateToken.ts +5 -4
|
@@ -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
|
+
}
|
package/api/editClan.ts
ADDED
|
@@ -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
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: {
|
package/utils/requestUtils.ts
CHANGED
|
@@ -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
|
|
package/utils/validateToken.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export function validateIntrinsicToken(token: string) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
}
|