some api routes
25
components/userInfo.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
import { useSession, signIn, signOut } from "next-auth/react";
|
||||
import styles from "../styles/Components.module.css";
|
||||
|
||||
export async function getServerSideProps(context) {
|
||||
return {
|
||||
props: {
|
||||
borderInfo,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default function UserInfo(borderInfo) {
|
||||
const { data: session } = useSession();
|
||||
return (
|
||||
<p className={styles.description}>
|
||||
{session ? `Signed in as ${session.user.name}` : "Not signed in"}
|
||||
<br />
|
||||
{session ? (
|
||||
<button onClick={() => signOut()}>Sign Out</button>
|
||||
) : (
|
||||
<button onClick={() => signIn()}>Sign In</button>
|
||||
)}
|
||||
</p>
|
||||
);
|
||||
}
|
43
lib/borders.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
import { getServerSession } from "next-auth";
|
||||
import { getSession } from "next-auth/react";
|
||||
import prisma from "./prisma";
|
||||
|
||||
export const getUserBorders = async (req) => {
|
||||
const session = await getSession({ req });
|
||||
if (!session) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const accountData = await prisma.account.findFirst({
|
||||
where: {
|
||||
userId: session.user.id,
|
||||
},
|
||||
});
|
||||
|
||||
const userData = await prisma.applicationUserData.findUnique({
|
||||
where: {
|
||||
userId: session.user.id,
|
||||
},
|
||||
});
|
||||
|
||||
if (!!userData) {
|
||||
return userData;
|
||||
}
|
||||
|
||||
const result = await prisma.applicationUserData.create({
|
||||
data: {
|
||||
userId: session.user.id,
|
||||
discordId: accountData.providerAccountId,
|
||||
},
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
export const getByDiscordId = async (id) => {
|
||||
const userData = await prisma.applicationUserData.findUnique({
|
||||
where: {
|
||||
discordId: id,
|
||||
},
|
||||
});
|
||||
return userData ? `${userData.borderId}` : undefined;
|
||||
};
|
14
lib/prisma.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
import { PrismaClient } from "@prisma/client";
|
||||
|
||||
let prisma;
|
||||
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
prisma = new PrismaClient();
|
||||
} else {
|
||||
if (!global.prisma) {
|
||||
global.prisma = new PrismaClient();
|
||||
}
|
||||
prisma = global.prisma;
|
||||
}
|
||||
|
||||
export default prisma;
|
|
@ -9,6 +9,8 @@
|
|||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@next-auth/prisma-adapter": "^1.0.3",
|
||||
"@prisma/client": "^3.12.0",
|
||||
"dotenv": "^16.0.0",
|
||||
"next": "12.1.4",
|
||||
"next-auth": "^4.3.1",
|
||||
|
|
|
@ -1,11 +1,21 @@
|
|||
import NextAuth from "next-auth";
|
||||
import DiscordProvider from "next-auth/providers/discord";
|
||||
import { PrismaAdapter } from "@next-auth/prisma-adapter";
|
||||
import prisma from "../../../lib/prisma";
|
||||
|
||||
export default NextAuth({
|
||||
adapter: PrismaAdapter(prisma),
|
||||
providers: [
|
||||
DiscordProvider({
|
||||
clientId: process.env.DISCORD_CLIENT_ID,
|
||||
clientSecret: process.env.DISCORD_CLIENT_SECRET,
|
||||
}),
|
||||
],
|
||||
callbacks: {
|
||||
async session({ session, token, user }) {
|
||||
session.user.id = user.id;
|
||||
console.log(JSON.stringify(user));
|
||||
return session;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
11
pages/api/user/border/@me.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
import { getUserBorders } from "../../../../lib/borders";
|
||||
|
||||
export default function handler(req, res) {
|
||||
getUserBorders(req).then((result) => {
|
||||
if (result) {
|
||||
return res.status(200).json(result);
|
||||
} else {
|
||||
return res.status(404).json({ error: "Not Found" });
|
||||
}
|
||||
});
|
||||
}
|
11
pages/api/user/border/[id].js
Normal file
|
@ -0,0 +1,11 @@
|
|||
import { getByDiscordId } from "../../../../lib/borders";
|
||||
|
||||
export default function handler(req, res) {
|
||||
const id = req.query.id;
|
||||
|
||||
getByDiscordId(id).then((result) => {
|
||||
const borderUrl = result ?? "0";
|
||||
|
||||
return res.status(200).send(borderUrl);
|
||||
});
|
||||
}
|
|
@ -1,10 +1,9 @@
|
|||
import { useSession, signIn, signOut } from "next-auth/react";
|
||||
import Head from "next/head";
|
||||
import Image from "next/image";
|
||||
import styles from "../styles/Home.module.css";
|
||||
import UserInfo from "../components/userInfo";
|
||||
|
||||
export default function Home() {
|
||||
const { data: session } = useSession();
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<Head>
|
||||
|
@ -15,16 +14,7 @@ export default function Home() {
|
|||
|
||||
<main className={styles.main}>
|
||||
<h1 className={styles.title}>Steam Borders</h1>
|
||||
|
||||
<p className={styles.description}>
|
||||
{session ? `Signed in as ${session.user.name}` : "Not signed in"}
|
||||
<br />
|
||||
{session ? (
|
||||
<button onClick={() => signOut()}>Sign Out</button>
|
||||
) : (
|
||||
<button onClick={() => signIn()}>Sign In</button>
|
||||
)}
|
||||
</p>
|
||||
<UserInfo />
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
lockfileVersion: 5.3
|
||||
|
||||
specifiers:
|
||||
'@next-auth/prisma-adapter': ^1.0.3
|
||||
'@prisma/client': ^3.12.0
|
||||
dotenv: ^16.0.0
|
||||
eslint: 8.13.0
|
||||
eslint-config-next: 12.1.4
|
||||
|
@ -11,6 +13,8 @@ specifiers:
|
|||
react-dom: 18.0.0
|
||||
|
||||
dependencies:
|
||||
'@next-auth/prisma-adapter': 1.0.3_2b535bbfb604d219371c9582b52b11b1
|
||||
'@prisma/client': 3.12.0_prisma@3.12.0
|
||||
dotenv: 16.0.0
|
||||
next: 12.1.4_react-dom@18.0.0+react@18.0.0
|
||||
next-auth: 4.3.1_react-dom@18.0.0+react@18.0.0
|
||||
|
@ -70,6 +74,16 @@ packages:
|
|||
resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
|
||||
dev: true
|
||||
|
||||
/@next-auth/prisma-adapter/1.0.3_2b535bbfb604d219371c9582b52b11b1:
|
||||
resolution: {integrity: sha512-3Lq1cD3ytKM3EGKJZ4UZvlqshLtlPvYxLeCrUV9ifYwYlq51kmDaHjsIawlp8EbH5pE1UhlsvtlXMery7RghtA==}
|
||||
peerDependencies:
|
||||
'@prisma/client': '>=2.26.0 || >=3'
|
||||
next-auth: ^4.0.1
|
||||
dependencies:
|
||||
'@prisma/client': 3.12.0_prisma@3.12.0
|
||||
next-auth: 4.3.1_react-dom@18.0.0+react@18.0.0
|
||||
dev: false
|
||||
|
||||
/@next/env/12.1.4:
|
||||
resolution: {integrity: sha512-7gQwotJDKnfMxxXd8xJ2vsX5AzyDxO3zou0+QOXX8/unypA6icw5+wf6A62yKZ6qQ4UZHHxS68pb6UV+wNneXg==}
|
||||
dev: false
|
||||
|
@ -213,6 +227,24 @@ packages:
|
|||
resolution: {integrity: sha512-mMyQ9vjpuFqePkfe5bZVIf/H3Dmk6wA8Kjxff9RcO4kqzJo+Ek9pGKwZHpeMr7Eku0QhLXMCd7fNCSnEnRMubg==}
|
||||
dev: false
|
||||
|
||||
/@prisma/client/3.12.0_prisma@3.12.0:
|
||||
resolution: {integrity: sha512-4NEQjUcWja/NVBvfuDFscWSk1/rXg3+wj+TSkqXCb1tKlx/bsUE00rxsvOvGg7VZ6lw1JFpGkwjwmsOIc4zvQw==}
|
||||
engines: {node: '>=12.6'}
|
||||
requiresBuild: true
|
||||
peerDependencies:
|
||||
prisma: '*'
|
||||
peerDependenciesMeta:
|
||||
prisma:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@prisma/engines-version': 3.12.0-37.22b822189f46ef0dc5c5b503368d1bee01213980
|
||||
prisma: 3.12.0
|
||||
dev: false
|
||||
|
||||
/@prisma/engines-version/3.12.0-37.22b822189f46ef0dc5c5b503368d1bee01213980:
|
||||
resolution: {integrity: sha512-o+jo8d7ZEiVpcpNWUDh3fj2uPQpBxl79XE9ih9nkogJbhw6P33274SHnqheedZ7PyvPIK/mvU8MLNYgetgXPYw==}
|
||||
dev: false
|
||||
|
||||
/@prisma/engines/3.12.0-37.22b822189f46ef0dc5c5b503368d1bee01213980:
|
||||
resolution: {integrity: sha512-zULjkN8yhzS7B3yeEz4aIym4E2w1ChrV12i14pht3ePFufvsAvBSoZ+tuXMvfSoNTgBS5E4bolRzLbMmbwkkMQ==}
|
||||
requiresBuild: true
|
||||
|
|
BIN
prisma/borders.db
Normal file
68
prisma/migrations/20220410164403_/migration.sql
Normal file
|
@ -0,0 +1,68 @@
|
|||
-- CreateTable
|
||||
CREATE TABLE "Account" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"userId" TEXT NOT NULL,
|
||||
"type" TEXT NOT NULL,
|
||||
"provider" TEXT NOT NULL,
|
||||
"providerAccountId" TEXT NOT NULL,
|
||||
"refresh_token" TEXT,
|
||||
"access_token" TEXT,
|
||||
"expires_at" INTEGER,
|
||||
"token_type" TEXT,
|
||||
"scope" TEXT,
|
||||
"id_token" TEXT,
|
||||
"session_state" TEXT,
|
||||
CONSTRAINT "Account_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Session" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"sessionToken" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"expires" DATETIME NOT NULL,
|
||||
CONSTRAINT "Session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "User" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"name" TEXT,
|
||||
"email" TEXT,
|
||||
"emailVerified" DATETIME,
|
||||
"image" TEXT
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "VerificationToken" (
|
||||
"identifier" TEXT NOT NULL,
|
||||
"token" TEXT NOT NULL,
|
||||
"expires" DATETIME NOT NULL
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ApplicationUserData" (
|
||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"discordId" TEXT NOT NULL,
|
||||
"borderUrl" TEXT,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Account_provider_providerAccountId_key" ON "Account"("provider", "providerAccountId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Session_sessionToken_key" ON "Session"("sessionToken");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "VerificationToken_token_key" ON "VerificationToken"("token");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "VerificationToken_identifier_token_key" ON "VerificationToken"("identifier", "token");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ApplicationUserData_discordId_key" ON "ApplicationUserData"("discordId");
|
22
prisma/migrations/20220410173021_/migration.sql
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `discordId` on the `ApplicationUserData` table. All the data in the column will be lost.
|
||||
- Added the required column `userId` to the `ApplicationUserData` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
-- RedefineTables
|
||||
PRAGMA foreign_keys=OFF;
|
||||
CREATE TABLE "new_ApplicationUserData" (
|
||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"userId" TEXT NOT NULL,
|
||||
"borderUrl" TEXT,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
INSERT INTO "new_ApplicationUserData" ("borderUrl", "createdAt", "id", "updatedAt") SELECT "borderUrl", "createdAt", "id", "updatedAt" FROM "ApplicationUserData";
|
||||
DROP TABLE "ApplicationUserData";
|
||||
ALTER TABLE "new_ApplicationUserData" RENAME TO "ApplicationUserData";
|
||||
CREATE UNIQUE INDEX "ApplicationUserData_userId_key" ON "ApplicationUserData"("userId");
|
||||
PRAGMA foreign_key_check;
|
||||
PRAGMA foreign_keys=ON;
|
23
prisma/migrations/20220410181303_/migration.sql
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
Warnings:
|
||||
|
||||
- Added the required column `discordId` to the `ApplicationUserData` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
-- RedefineTables
|
||||
PRAGMA foreign_keys=OFF;
|
||||
CREATE TABLE "new_ApplicationUserData" (
|
||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"userId" TEXT NOT NULL,
|
||||
"discordId" TEXT NOT NULL,
|
||||
"borderUrl" TEXT,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
INSERT INTO "new_ApplicationUserData" ("borderUrl", "createdAt", "id", "updatedAt", "userId") SELECT "borderUrl", "createdAt", "id", "updatedAt", "userId" FROM "ApplicationUserData";
|
||||
DROP TABLE "ApplicationUserData";
|
||||
ALTER TABLE "new_ApplicationUserData" RENAME TO "ApplicationUserData";
|
||||
CREATE UNIQUE INDEX "ApplicationUserData_userId_key" ON "ApplicationUserData"("userId");
|
||||
CREATE UNIQUE INDEX "ApplicationUserData_discordId_key" ON "ApplicationUserData"("discordId");
|
||||
PRAGMA foreign_key_check;
|
||||
PRAGMA foreign_keys=ON;
|
3
prisma/migrations/migration_lock.toml
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (i.e. Git)
|
||||
provider = "sqlite"
|
|
@ -10,13 +10,62 @@ datasource db {
|
|||
url = "file:./borders.db"
|
||||
}
|
||||
|
||||
model User {
|
||||
id Int @id @default(autoincrement())
|
||||
discordId String @unique
|
||||
username String
|
||||
discriminator String
|
||||
avatar String?
|
||||
borderUrl String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
model Account {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
type String
|
||||
provider String
|
||||
providerAccountId String
|
||||
refresh_token String?
|
||||
access_token String?
|
||||
expires_at Int?
|
||||
token_type String?
|
||||
scope String?
|
||||
id_token String?
|
||||
session_state String?
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([provider, providerAccountId])
|
||||
}
|
||||
|
||||
model Session {
|
||||
id String @id @default(cuid())
|
||||
sessionToken String @unique
|
||||
userId String
|
||||
expires DateTime
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
name String?
|
||||
email String? @unique
|
||||
emailVerified DateTime?
|
||||
image String?
|
||||
accounts Account[]
|
||||
sessions Session[]
|
||||
}
|
||||
|
||||
model VerificationToken {
|
||||
identifier String
|
||||
token String @unique
|
||||
expires DateTime
|
||||
|
||||
@@unique([identifier, token])
|
||||
}
|
||||
|
||||
model ApplicationUserData {
|
||||
id Int @id @default(autoincrement())
|
||||
userId String @unique
|
||||
discordId String @unique
|
||||
admin Boolean?
|
||||
borderId Int?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model BorderImage {
|
||||
id Int @id @default(autoincrement())
|
||||
imageName String @unique
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 17 KiB |
BIN
public/images/00b9a62e09a1e452d6840170849e8ac06f6d3ef5.png
Normal file
After Width: | Height: | Size: 526 KiB |
BIN
public/images/083c19cc935001ee0508aff3b948da62b6a093f6.png
Normal file
After Width: | Height: | Size: 897 KiB |
BIN
public/images/18717998311ff5e68b1246dbdb43cbc0fa00a35d.png
Normal file
After Width: | Height: | Size: 573 KiB |
BIN
public/images/27ef3d62a0e42bf4ac60d426f2f172e1790ec0fd.png
Normal file
After Width: | Height: | Size: 236 KiB |
BIN
public/images/2d876cff5940a8724340a5798c1c8e48880c675f.png
Normal file
After Width: | Height: | Size: 622 KiB |
BIN
public/images/359032c610e13a8f370594b200b9ddf8b29aa8af.png
Normal file
After Width: | Height: | Size: 588 KiB |
BIN
public/images/3fd73db5d33e9b6597e6975eb654e89b89b5db5c.png
Normal file
After Width: | Height: | Size: 1.9 MiB |
BIN
public/images/420efee31f0b0a3fe39cb7409dbe9c3a3e0a0e3a.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
public/images/46461aaea39b18a4a3da2e6d3cf253006f2d6193.png
Normal file
After Width: | Height: | Size: 653 KiB |
BIN
public/images/4718aad9a4b04c3cfb049bb7cbf2bd35c2e2eb11.png
Normal file
After Width: | Height: | Size: 569 KiB |
BIN
public/images/537ab433b4dbf1c225e5809ad53d690ee73438d8.png
Normal file
After Width: | Height: | Size: 346 KiB |
BIN
public/images/558efce86af3043bda6ac5078e1801dc7b587de7.png
Normal file
After Width: | Height: | Size: 1.9 MiB |
BIN
public/images/68439f85ae83ce6429b845234e28de62a88b1f88.png
Normal file
After Width: | Height: | Size: 686 KiB |
BIN
public/images/950172e5379f52079835a2b295e93de1d8a8fbf3.png
Normal file
After Width: | Height: | Size: 140 KiB |
BIN
public/images/984f18d4bcc76669bcbd8971f962d1b75716dd11.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
public/images/babb8c618b2c8eafaad9bc3fac3304a1837ac4fb.png
Normal file
After Width: | Height: | Size: 1 MiB |
BIN
public/images/bd04ee3a8e6c35c39f8670c034a5ea7fd15ca3f1.png
Normal file
After Width: | Height: | Size: 938 KiB |
BIN
public/images/beaee5e90d93bfafa5f5f55acb23abfd28ad180c.png
Normal file
After Width: | Height: | Size: 470 KiB |
BIN
public/images/c30260bb120bf1379f075802653c8eb86da7a7e9.png
Normal file
After Width: | Height: | Size: 92 KiB |
BIN
public/images/e0de1bf39208a3c1230bca5bc69561e9d2f0971f.png
Normal file
After Width: | Height: | Size: 7.4 KiB |
BIN
public/images/e89b3a70625c980c3d68869f5cdb1da9baa447f8.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
public/sky.png
Normal file
After Width: | Height: | Size: 118 KiB |