rhythia-api 151.0.0 → 152.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/approveMap.ts CHANGED
@@ -2,6 +2,8 @@ import { NextResponse } from "next/server";
2
2
  import z from "zod";
3
3
  import { protectedApi, validUser } from "../utils/requestUtils";
4
4
  import { supabase } from "../utils/supabase";
5
+ import { getUserBySession } from "../utils/getUserBySession";
6
+ import { User } from "@supabase/supabase-js";
5
7
 
6
8
  export const Schema = {
7
9
  input: z.strictObject({
@@ -23,7 +25,7 @@ export async function POST(request: Request) {
23
25
  }
24
26
 
25
27
  export async function handler(data: (typeof Schema)["input"]["_type"]) {
26
- const user = (await supabase.auth.getUser(data.session)).data.user!;
28
+ const user = (await getUserBySession(data.session)) as User;
27
29
  let { data: queryUserData, error: userError } = await supabase
28
30
  .from("profiles")
29
31
  .select("*")
@@ -5,6 +5,8 @@ import { SSPMParser } from "../utils/star-calc/sspmParser";
5
5
  import { supabase } from "../utils/supabase";
6
6
  import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
7
7
  import { rateMap } from "../utils/star-calc";
8
+ import { getUserBySession } from "../utils/getUserBySession";
9
+ import { User } from "@supabase/supabase-js";
8
10
  const s3Client = new S3Client({
9
11
  region: "auto",
10
12
  endpoint: "https://s3.eu-central-003.backblazeb2.com",
@@ -52,7 +54,7 @@ export async function handler({
52
54
  const parsedData = parser.parse();
53
55
  const digested = parsedData.strings.mapID;
54
56
 
55
- const user = (await supabase.auth.getUser(session)).data.user!;
57
+ const user = (await getUserBySession(session)) as User;
56
58
  let { data: userData, error: userError } = await supabase
57
59
  .from("profiles")
58
60
  .select("*")
@@ -2,6 +2,8 @@ import { NextResponse } from "next/server";
2
2
  import z from "zod";
3
3
  import { protectedApi, validUser } from "../utils/requestUtils";
4
4
  import { supabase } from "../utils/supabase";
5
+ import { getUserBySession } from "../utils/getUserBySession";
6
+ import { User } from "@supabase/supabase-js";
5
7
 
6
8
  export const Schema = {
7
9
  input: z.strictObject({
@@ -27,7 +29,7 @@ export async function handler({
27
29
  }: (typeof Schema)["input"]["_type"]): Promise<
28
30
  NextResponse<(typeof Schema)["output"]["_type"]>
29
31
  > {
30
- const user = (await supabase.auth.getUser(session)).data.user!;
32
+ const user = (await getUserBySession(session)) as User;
31
33
  let { data: userData, error: userError } = await supabase
32
34
  .from("profiles")
33
35
  .select("*")
@@ -49,7 +51,7 @@ export async function handler({
49
51
  { status: 404 }
50
52
  );
51
53
  }
52
-
54
+
53
55
  const upserted = await supabase
54
56
  .from("beatmapPages")
55
57
  .upsert({
@@ -2,6 +2,8 @@ import { NextResponse } from "next/server";
2
2
  import z from "zod";
3
3
  import { protectedApi, validUser } from "../utils/requestUtils";
4
4
  import { supabase } from "../utils/supabase";
5
+ import { getUserBySession } from "../utils/getUserBySession";
6
+ import { User } from "@supabase/supabase-js";
5
7
 
6
8
  export const Schema = {
7
9
  input: z.strictObject({
@@ -28,7 +30,7 @@ export async function handler({
28
30
  }: (typeof Schema)["input"]["_type"]): Promise<
29
31
  NextResponse<(typeof Schema)["output"]["_type"]>
30
32
  > {
31
- const user = (await supabase.auth.getUser(session)).data.user!;
33
+ const user = (await getUserBySession(session)) as User;
32
34
  let { data: userData, error: userError } = await supabase
33
35
  .from("profiles")
34
36
  .select("*")
@@ -3,6 +3,8 @@ import z from "zod";
3
3
  import { Database } from "../types/database";
4
4
  import { protectedApi, validUser } from "../utils/requestUtils";
5
5
  import { supabase } from "../utils/supabase";
6
+ import { getUserBySession } from "../utils/getUserBySession";
7
+ import { User } from "@supabase/supabase-js";
6
8
  export const Schema = {
7
9
  input: z.strictObject({
8
10
  session: z.string(),
@@ -45,7 +47,7 @@ export async function handler(
45
47
  );
46
48
  }
47
49
 
48
- const user = (await supabase.auth.getUser(data.session)).data.user!;
50
+ const user = (await getUserBySession(data.session)) as User;
49
51
  let userData: Database["public"]["Tables"]["profiles"]["Update"];
50
52
 
51
53
  // Find user's entry
@@ -3,6 +3,8 @@ import z from "zod";
3
3
  import { Database } from "../types/database";
4
4
  import { protectedApi, validUser } from "../utils/requestUtils";
5
5
  import { supabase } from "../utils/supabase";
6
+ import { getUserBySession } from "../utils/getUserBySession";
7
+ import { User } from "@supabase/supabase-js";
6
8
  export const Schema = {
7
9
  input: z.strictObject({
8
10
  session: z.string(),
@@ -46,7 +48,7 @@ export async function handler(
46
48
  );
47
49
  }
48
50
 
49
- const user = (await supabase.auth.getUser(data.session)).data.user!;
51
+ const user = (await getUserBySession(data.session)) as User;
50
52
 
51
53
  let userData: Database["public"]["Tables"]["profiles"]["Update"];
52
54
 
@@ -10,6 +10,8 @@ import {
10
10
  } from "@aws-sdk/client-s3";
11
11
  import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
12
12
  import { validateIntrinsicToken } from "../utils/validateToken";
13
+ import { getUserBySession } from "../utils/getUserBySession";
14
+ import { User } from "@supabase/supabase-js";
13
15
 
14
16
  const s3Client = new S3Client({
15
17
  region: "auto",
@@ -51,7 +53,7 @@ export async function handler({
51
53
  }: (typeof Schema)["input"]["_type"]): Promise<
52
54
  NextResponse<(typeof Schema)["output"]["_type"]>
53
55
  > {
54
- const user = (await supabase.auth.getUser(session)).data.user!;
56
+ const user = (await getUserBySession(session)) as User;
55
57
 
56
58
  if (!validateIntrinsicToken(intrinsicToken)) {
57
59
  return NextResponse.json({
@@ -1,6 +1,6 @@
1
1
  import { NextResponse } from "next/server";
2
2
  import z from "zod";
3
- import { getUser, protectedApi } from "../utils/requestUtils";
3
+ import { protectedApi } from "../utils/requestUtils";
4
4
  import { supabase } from "../utils/supabase";
5
5
 
6
6
  export const Schema = {
@@ -1,7 +1,9 @@
1
1
  import { NextResponse } from "next/server";
2
2
  import z from "zod";
3
- import { getUser, protectedApi } from "../utils/requestUtils";
3
+ import { protectedApi } from "../utils/requestUtils";
4
4
  import { supabase } from "../utils/supabase";
5
+ import { getUserBySession } from "../utils/getUserBySession";
6
+ import { User } from "@supabase/supabase-js";
5
7
 
6
8
  export const Schema = {
7
9
  input: z.strictObject({
@@ -48,7 +50,7 @@ export async function handler(
48
50
  const VIEW_PER_PAGE = 50;
49
51
 
50
52
  export async function getLeaderboard(page = 1, session: string) {
51
- const getUserData = await getUser({ session });
53
+ const getUserData = (await getUserBySession(session)) as User;
52
54
 
53
55
  let leaderPosition = 0;
54
56
 
@@ -56,7 +58,7 @@ export async function getLeaderboard(page = 1, session: string) {
56
58
  let { data: queryData, error } = await supabase
57
59
  .from("profiles")
58
60
  .select("*")
59
- .eq("uid", getUserData.data.user.id)
61
+ .eq("uid", getUserData.id)
60
62
  .single();
61
63
 
62
64
  if (queryData) {
@@ -10,6 +10,8 @@ import {
10
10
  } from "@aws-sdk/client-s3";
11
11
  import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
12
12
  import { validateIntrinsicToken } from "../utils/validateToken";
13
+ import { getUserBySession } from "../utils/getUserBySession";
14
+ import { User } from "@supabase/supabase-js";
13
15
 
14
16
  const s3Client = new S3Client({
15
17
  region: "auto",
@@ -53,7 +55,7 @@ export async function handler({
53
55
  }: (typeof Schema)["input"]["_type"]): Promise<
54
56
  NextResponse<(typeof Schema)["output"]["_type"]>
55
57
  > {
56
- const user = (await supabase.auth.getUser(session)).data.user!;
58
+ const user = (await getUserBySession(session)) as User;
57
59
 
58
60
  if (!validateIntrinsicToken(intrinsicToken)) {
59
61
  return NextResponse.json({
@@ -0,0 +1,56 @@
1
+ import { NextResponse } from "next/server";
2
+ import z from "zod";
3
+ import { Database } from "../types/database";
4
+ import { protectedApi, validUser } from "../utils/requestUtils";
5
+ import { supabase } from "../utils/supabase";
6
+ import md5 from "md5";
7
+ import { encryptString } from "../utils/security";
8
+ export const Schema = {
9
+ input: z.strictObject({
10
+ data: z.object({
11
+ email: z.string(),
12
+ passkey: z.string(),
13
+ computerName: z.string(),
14
+ }),
15
+ }),
16
+ output: z.object({
17
+ token: z.string().optional(),
18
+ error: z.string().optional(),
19
+ }),
20
+ };
21
+
22
+ export async function POST(request: Request): Promise<NextResponse> {
23
+ return protectedApi({
24
+ request,
25
+ schema: Schema,
26
+ authorization: () => {},
27
+ activity: handler,
28
+ });
29
+ }
30
+
31
+ export async function handler(
32
+ data: (typeof Schema)["input"]["_type"]
33
+ ): Promise<NextResponse<(typeof Schema)["output"]["_type"]>> {
34
+ let { data: queryPasskey, error } = await supabase
35
+ .from("passkeys")
36
+ .select("*")
37
+ .eq("email", data.data.email)
38
+ .eq("passkey", data.data.passkey)
39
+ .single();
40
+
41
+ if (!queryPasskey) {
42
+ return NextResponse.json({
43
+ error: "Wrong combination",
44
+ });
45
+ }
46
+ return NextResponse.json({
47
+ token: encryptString(
48
+ JSON.stringify({
49
+ userId: queryPasskey.id,
50
+ email: queryPasskey.email,
51
+ passKey: queryPasskey.passkey,
52
+ computerName: data.data.computerName,
53
+ })
54
+ ),
55
+ });
56
+ }
@@ -2,6 +2,8 @@ import { NextResponse } from "next/server";
2
2
  import z from "zod";
3
3
  import { protectedApi, validUser } from "../utils/requestUtils";
4
4
  import { supabase } from "../utils/supabase";
5
+ import { getUserBySession } from "../utils/getUserBySession";
6
+ import { User } from "@supabase/supabase-js";
5
7
 
6
8
  export const Schema = {
7
9
  input: z.strictObject({
@@ -23,7 +25,7 @@ export async function POST(request: Request) {
23
25
  }
24
26
 
25
27
  export async function handler(data: (typeof Schema)["input"]["_type"]) {
26
- const user = (await supabase.auth.getUser(data.session)).data.user!;
28
+ const user = (await getUserBySession(data.session)) as User;
27
29
  let { data: queryUserData, error: userError } = await supabase
28
30
  .from("profiles")
29
31
  .select("*")
@@ -2,6 +2,8 @@ import { NextResponse } from "next/server";
2
2
  import z from "zod";
3
3
  import { protectedApi, validUser } from "../utils/requestUtils";
4
4
  import { supabase } from "../utils/supabase";
5
+ import { User } from "@supabase/supabase-js";
6
+ import { getUserBySession } from "../utils/getUserBySession";
5
7
 
6
8
  export const Schema = {
7
9
  input: z.strictObject({
@@ -30,7 +32,7 @@ export async function handler({
30
32
  }: (typeof Schema)["input"]["_type"]): Promise<
31
33
  NextResponse<(typeof Schema)["output"]["_type"]>
32
34
  > {
33
- const user = (await supabase.auth.getUser(session)).data.user!;
35
+ const user = (await getUserBySession(session)) as User;
34
36
  let { data: userData, error: userError } = await supabase
35
37
  .from("profiles")
36
38
  .select("*")
@@ -2,6 +2,8 @@ import { NextResponse } from "next/server";
2
2
  import z from "zod";
3
3
  import { protectedApi, validUser } from "../utils/requestUtils";
4
4
  import { supabase } from "../utils/supabase";
5
+ import { getUserBySession } from "../utils/getUserBySession";
6
+ import { User } from "@supabase/supabase-js";
5
7
 
6
8
  export const Schema = {
7
9
  input: z.strictObject({
@@ -23,7 +25,7 @@ export async function POST(request: Request) {
23
25
  }
24
26
 
25
27
  export async function handler(data: (typeof Schema)["input"]["_type"]) {
26
- const user = (await supabase.auth.getUser(data.session)).data.user!;
28
+ const user = (await getUserBySession(data.session)) as User;
27
29
  let { data: queryUserData, error: userError } = await supabase
28
30
  .from("profiles")
29
31
  .select("*")
@@ -0,0 +1,60 @@
1
+ import { NextResponse } from "next/server";
2
+ import z from "zod";
3
+ import { Database } from "../types/database";
4
+ import { protectedApi, validUser } from "../utils/requestUtils";
5
+ import { supabase } from "../utils/supabase";
6
+ import md5 from "md5";
7
+ import { getUserBySession } from "../utils/getUserBySession";
8
+ import { User } from "@supabase/supabase-js";
9
+ export const Schema = {
10
+ input: z.strictObject({
11
+ session: z.string(),
12
+ data: z.object({
13
+ passkey: z.string(),
14
+ }),
15
+ }),
16
+ output: z.object({
17
+ error: z.string().optional(),
18
+ }),
19
+ };
20
+
21
+ export async function POST(request: Request): Promise<NextResponse> {
22
+ return protectedApi({
23
+ request,
24
+ schema: Schema,
25
+ authorization: () => {},
26
+ activity: handler,
27
+ });
28
+ }
29
+
30
+ export async function handler(
31
+ data: (typeof Schema)["input"]["_type"]
32
+ ): Promise<NextResponse<(typeof Schema)["output"]["_type"]>> {
33
+ const user = (await getUserBySession(data.session)) as User;
34
+ let userData: Database["public"]["Tables"]["profiles"]["Update"];
35
+ // Find user's entry
36
+ {
37
+ let { data: queryUserData, error } = await supabase
38
+ .from("profiles")
39
+ .select("*")
40
+ .eq("uid", user.id);
41
+
42
+ if (!queryUserData?.length) {
43
+ return NextResponse.json(
44
+ {
45
+ error: "User cannot be retrieved from session",
46
+ },
47
+ { status: 404 }
48
+ );
49
+ }
50
+ userData = queryUserData[0];
51
+ }
52
+
53
+ await supabase.from("passkeys").upsert({
54
+ id: userData.id!,
55
+ email: user.email!,
56
+ passkey: md5(data.data.passkey),
57
+ });
58
+
59
+ return NextResponse.json({});
60
+ }
@@ -2,6 +2,10 @@ import { NextResponse } from "next/server";
2
2
  import z from "zod";
3
3
  import { protectedApi, validUser } from "../utils/requestUtils";
4
4
  import { supabase } from "../utils/supabase";
5
+ import { decryptString } from "../utils/security";
6
+ import { isEqual } from "lodash";
7
+ import { getUserBySession } from "../utils/getUserBySession";
8
+ import { User } from "@supabase/supabase-js";
5
9
 
6
10
  export const Schema = {
7
11
  input: z.strictObject({
@@ -50,13 +54,27 @@ export async function handler({
50
54
  }: (typeof Schema)["input"]["_type"]): Promise<
51
55
  NextResponse<(typeof Schema)["output"]["_type"]>
52
56
  > {
53
- return NextResponse.json(
54
- {
55
- error: "Disabled",
56
- },
57
- { status: 500 }
58
- );
59
- const user = (await supabase.auth.getUser(session)).data.user!;
57
+ const tokenContents = JSON.parse(decryptString(data.token));
58
+ if (
59
+ !isEqual(tokenContents, {
60
+ relayHwid: data.relayHwid,
61
+ songId: data.songId,
62
+ misses: data.misses,
63
+ hits: data.hits,
64
+ mapHash: data.mapHash,
65
+ mapNoteCount: data.mapNoteCount,
66
+ speed: data.speed,
67
+ })
68
+ ) {
69
+ return NextResponse.json(
70
+ {
71
+ error: "Token miscalculation",
72
+ },
73
+ { status: 500 }
74
+ );
75
+ }
76
+
77
+ const user = (await getUserBySession(session)) as User;
60
78
 
61
79
  let { data: userData, error: userError } = await supabase
62
80
  .from("profiles")
@@ -2,6 +2,8 @@ import { NextResponse } from "next/server";
2
2
  import z from "zod";
3
3
  import { protectedApi, validUser } from "../utils/requestUtils";
4
4
  import { supabase } from "../utils/supabase";
5
+ import { getUserBySession } from "../utils/getUserBySession";
6
+ import { User } from "@supabase/supabase-js";
5
7
 
6
8
  export const Schema = {
7
9
  input: z.strictObject({
@@ -34,7 +36,7 @@ export async function handler({
34
36
  }: (typeof Schema)["input"]["_type"]): Promise<
35
37
  NextResponse<(typeof Schema)["output"]["_type"]>
36
38
  > {
37
- const user = (await supabase.auth.getUser(session)).data.user!;
39
+ const user = (await getUserBySession(session)) as User;
38
40
  let { data: userData, error: userError } = await supabase
39
41
  .from("profiles")
40
42
  .select("*")
package/index.ts CHANGED
@@ -353,6 +353,26 @@ import { Schema as GetMapUploadUrl } from "./api/getMapUploadUrl"
353
353
  export { Schema as SchemaGetMapUploadUrl } from "./api/getMapUploadUrl"
354
354
  export const getMapUploadUrl = handleApi({url:"/api/getMapUploadUrl",...GetMapUploadUrl})
355
355
 
356
+ // ./api/getPassToken.ts API
357
+
358
+ /*
359
+ export const Schema = {
360
+ input: z.strictObject({
361
+ data: z.object({
362
+ email: z.string(),
363
+ passkey: z.string(),
364
+ computerName: z.string(),
365
+ }),
366
+ }),
367
+ output: z.object({
368
+ token: z.string().optional(),
369
+ error: z.string().optional(),
370
+ }),
371
+ };*/
372
+ import { Schema as GetPassToken } from "./api/getPassToken"
373
+ export { Schema as SchemaGetPassToken } from "./api/getPassToken"
374
+ export const getPassToken = handleApi({url:"/api/getPassToken",...GetPassToken})
375
+
356
376
  // ./api/getProfile.ts API
357
377
 
358
378
  /*
@@ -562,6 +582,24 @@ import { Schema as SearchUsers } from "./api/searchUsers"
562
582
  export { Schema as SchemaSearchUsers } from "./api/searchUsers"
563
583
  export const searchUsers = handleApi({url:"/api/searchUsers",...SearchUsers})
564
584
 
585
+ // ./api/setPasskey.ts API
586
+
587
+ /*
588
+ export const Schema = {
589
+ input: z.strictObject({
590
+ session: z.string(),
591
+ data: z.object({
592
+ passkey: z.string(),
593
+ }),
594
+ }),
595
+ output: z.object({
596
+ error: z.string().optional(),
597
+ }),
598
+ };*/
599
+ import { Schema as SetPasskey } from "./api/setPasskey"
600
+ export { Schema as SchemaSetPasskey } from "./api/setPasskey"
601
+ export const setPasskey = handleApi({url:"/api/setPasskey",...SetPasskey})
602
+
565
603
  // ./api/submitScore.ts API
566
604
 
567
605
  /*
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rhythia-api",
3
- "version": "151.0.0",
3
+ "version": "152.0.0",
4
4
  "main": "index.ts",
5
5
  "scripts": {
6
6
  "update": "bun ./scripts/update.ts",
@@ -16,6 +16,7 @@
16
16
  "@aws-sdk/client-s3": "^3.637.0",
17
17
  "@aws-sdk/s3-request-presigner": "^3.637.0",
18
18
  "@netlify/zip-it-and-ship-it": "^9.37.9",
19
+ "@noble/ciphers": "^1.0.0",
19
20
  "@supabase/supabase-js": "^2.45.1",
20
21
  "@types/aws-lambda": "^8.10.143",
21
22
  "@types/bun": "^1.1.6",
package/types/database.ts CHANGED
@@ -147,6 +147,32 @@ export type Database = {
147
147
  }
148
148
  Relationships: []
149
149
  }
150
+ passkeys: {
151
+ Row: {
152
+ email: string
153
+ id: number
154
+ passkey: string
155
+ }
156
+ Insert: {
157
+ email: string
158
+ id: number
159
+ passkey: string
160
+ }
161
+ Update: {
162
+ email?: string
163
+ id?: number
164
+ passkey?: string
165
+ }
166
+ Relationships: [
167
+ {
168
+ foreignKeyName: "passkeys_id_fkey"
169
+ columns: ["id"]
170
+ isOneToOne: true
171
+ referencedRelation: "profiles"
172
+ referencedColumns: ["id"]
173
+ },
174
+ ]
175
+ }
150
176
  profiles: {
151
177
  Row: {
152
178
  about_me: string | null
@@ -0,0 +1,37 @@
1
+ import { User } from "@supabase/supabase-js";
2
+ import { decryptString } from "./security";
3
+ import { supabase } from "./supabase";
4
+
5
+ export async function getUserBySession(session: string): Promise<User | null> {
6
+ const user = (await supabase.auth.getUser(session)).data.user;
7
+
8
+ if (user) {
9
+ return user;
10
+ }
11
+
12
+ try {
13
+ const decryptedToken = JSON.parse(decryptString(session)) as {
14
+ userId: number;
15
+ email: string;
16
+ passKey: string;
17
+ computerName: string;
18
+ };
19
+
20
+ let { data: queryPasskey, error } = await supabase
21
+ .from("passkeys")
22
+ .select("*,profiles(uid)")
23
+ .eq("id", decryptedToken.userId || "nil")
24
+ .eq("email", decryptedToken.email || "nil")
25
+ .eq("passkey", decryptedToken.passKey || "nil")
26
+ .single();
27
+
28
+ if (!queryPasskey) {
29
+ return null;
30
+ }
31
+
32
+ return (await supabase.auth.admin.getUserById(queryPasskey.profiles?.uid!))
33
+ .data.user;
34
+ } catch (error) {}
35
+
36
+ return null;
37
+ }
@@ -1,6 +1,6 @@
1
1
  import { NextResponse } from "next/server";
2
- import { supabase } from "./supabase";
3
2
  import { ZodObject } from "zod";
3
+ import { getUserBySession } from "./getUserBySession";
4
4
 
5
5
  interface Props<
6
6
  K = (...args: any[]) => Promise<NextResponse<any>>,
@@ -43,8 +43,8 @@ export async function validUser(data) {
43
43
  );
44
44
  }
45
45
 
46
- const user = await supabase.auth.getUser(data.session);
47
- if (user.error || !user.data.user) {
46
+ const user = await getUserBySession(data.session);
47
+ if (!user) {
48
48
  return NextResponse.json(
49
49
  {
50
50
  error: "Invalid user session",
@@ -53,15 +53,3 @@ export async function validUser(data) {
53
53
  );
54
54
  }
55
55
  }
56
-
57
- export async function getUser(data) {
58
- if (!data.session) {
59
- return;
60
- }
61
-
62
- const user = await supabase.auth.getUser(data.session);
63
- if (user.error || !user.data.user) {
64
- return;
65
- }
66
- return user;
67
- }
@@ -0,0 +1,20 @@
1
+ import { xchacha20poly1305 } from "@noble/ciphers/chacha";
2
+ import { managedNonce } from "@noble/ciphers/webcrypto";
3
+ import {
4
+ bytesToHex,
5
+ bytesToUtf8,
6
+ hexToBytes,
7
+ utf8ToBytes,
8
+ } from "@noble/ciphers/utils";
9
+ const key = hexToBytes(process.env.TOKEN_SECRET || "");
10
+ const chacha = managedNonce(xchacha20poly1305)(key); // manages nonces for you
11
+
12
+ export function encryptString(str: string) {
13
+ const data = utf8ToBytes(str);
14
+ return bytesToHex(chacha.encrypt(data));
15
+ }
16
+
17
+ export function decryptString(str: string) {
18
+ const data = hexToBytes(str);
19
+ return bytesToUtf8(chacha.decrypt(data));
20
+ }
@@ -48,7 +48,6 @@ export function rate(
48
48
  ) {
49
49
  notes = notes.sort((a, b) => a.time - b.time);
50
50
  const decoder = new BeatmapDecoder();
51
- const encoder = new BeatmapEncoder();
52
51
  const beatmap1 = decoder.decodeFromString(sampleMap);
53
52
  let i = 0;
54
53
  while (i < notes.length - 1) {
@@ -70,7 +69,6 @@ export function rate(
70
69
  const mods = ruleset.createModCombination("RX");
71
70
  const difficultyCalculator = ruleset.createDifficultyCalculator(beatmap1);
72
71
  const difficultyAttributes = difficultyCalculator.calculateWithMods(mods);
73
- encoder.encodeToPath("./map.osu", beatmap1);
74
72
  return difficultyAttributes.starRating;
75
73
  }
76
74