Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,20 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@master

- name: Install Node v14
uses: actions/setup-node@v2
with:
node-version: '14'

- name: Install dependencies
run: npm install

- name: Generate prisma client
run: npx prisma generate

- name: Run Linter
run: npm run lint

- name: Run typescript pretty check
run: npm run tspretty
run: npm run tspretty
7 changes: 1 addition & 6 deletions components/user/DropDown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ import Link from 'next/link';
import { signOut } from 'next-auth/react';
import React, { Fragment } from 'react';
import styles from 'styles/navbar.module.scss';
import { ApiUser } from 'typings/typings';

interface props {
user: ApiUser;
}

function AccountSettingsIcon() {
return (
Expand Down Expand Up @@ -69,7 +64,7 @@ function ProfileIcon() {
// },
// ];

export default function UserDropDown({ user }: props) {
export default function UserDropDown({ user }) {
return (
<Menu as={Fragment}>
<Menu.Button className={styles.user_button}>
Expand Down
2 changes: 1 addition & 1 deletion components/user/Loader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default function UserLoader() {
}

if (status === 'authenticated') {
return <UserDropDown user={session.user as ApiUser} />;
return <UserDropDown user={session.user} />;
}

return (
Expand Down
File renamed without changes.
10 changes: 10 additions & 0 deletions lib/prisma.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { PrismaClient } from '@prisma/client';

declare global {
// eslint-disable-next-line vars-on-top, no-var
var prisma: PrismaClient | undefined;
}

export const prisma = global.prisma || new PrismaClient();

if (process.env.NODE_ENV !== 'production') global.prisma = prisma;
95 changes: 95 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
"dependencies": {
"@headlessui/react": "^1.2.0",
"@next-auth/mongodb-adapter": "^0.0.2-next.298",
"@next-auth/prisma-adapter": "^0.5.2-next.19",
"@popperjs/core": "^2.9.2",
"@prisma/client": "^3.5.0",
"@y0c/react-datepicker": "^1.0.4",
"axios": "^0.24.0",
"btoa": "^1.2.1",
Expand Down Expand Up @@ -79,6 +81,7 @@
"lint-staged": "^10.4.2",
"postcss": "^8.3.0",
"prettier": "^2.2.1",
"prisma": "^3.5.0",
"sass": "^1.32.13",
"typescript": "^4.2.4"
}
Expand Down
36 changes: 20 additions & 16 deletions pages/api/auth/[...nextauth].ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,19 @@
import { MongoDBAdapter } from '@next-auth/mongodb-adapter';
import { PrismaAdapter } from '@next-auth/prisma-adapter';
import { hasBetaAccess } from 'lib/backend-utils';
import clientPromise from 'lib/mongodb';
import { prisma } from 'lib/prisma';
import NextAuth from 'next-auth';
import Discord from 'next-auth/providers/discord';

interface User {
id: string;
username: string;
discriminator: string;
avatar: string;
email: string;
verified: boolean;
public_flags: number;
}

export default NextAuth({
adapter: MongoDBAdapter(clientPromise),
adapter: PrismaAdapter(prisma),
providers: [
Discord({
clientId: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
authorization: 'https://discord.com/api/oauth2/authorize?scope=identify+guilds',
profile(profile) {
let image_url: string;
let banner: string;

if (profile.avatar === null) {
const defaultAvatarNumber = parseInt(profile.discriminator, 10) % 5;
Expand All @@ -32,15 +23,27 @@ export default NextAuth({
image_url = `https://cdn.discordapp.com/avatars/${profile.id}/${profile.avatar}.${format}`;
}

if (profile.banner === null) {
banner = `color:${profile.banner_color}`;
} else {
const format = profile.avatar.startsWith('a_') ? 'gif' : 'png';
banner = `https://cdn.discordapp.com/banners/${profile.id}/${profile.banner}.${format}`;
}

return {
id: profile.id,
uid: profile.id,
username: profile.username,
discriminator: profile.discriminator,
avatar: image_url,
verified: profile.verified,
public_flags: profile.public_flags,
vanity: `${profile.id}`,
profile: {
create: {
bio: "I'm new to dmod! Not much is known about me yet :(",
public: false,
banner,
flags: 0,
},
},
};
},
}),
Expand All @@ -61,4 +64,5 @@ export default NextAuth({
return betaUser ? true : '/?error=AccessDenied';
},
},
secret: process.env.AUTH_SECRET,
});
72 changes: 72 additions & 0 deletions pages/api/guilds/fetch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { prisma } from 'lib/prisma';
import type { NextApiRequest, NextApiResponse } from 'next';
import { getSession } from 'next-auth/react';

const endpoint = 'https://discord.com/api/users/@me/guilds';

// GET users/sync - sync user data with Discord
export default async (req: NextApiRequest, res: NextApiResponse) => {
// Get session
const session = await getSession({ req });

// Check if user is logged in
if (!session) {
res.status(401).json({ message: 'Unauthorized' });
return;
}

// Get access token for the session from the database
const { access_token } = await prisma.account.findFirst({
where: {
userId: session.user.id,
},
select: {
access_token: true,
},
});

// Get guilds from Discord
const discord_guilds = await fetch(endpoint, {
headers: {
Authorization: `Bearer ${access_token}`,
},
}).then((r) => r.json());

// Get guilds from the database
const db_guilds = await prisma.guild.findMany({
where: {
members: {
some: {
userId: session.user.id,
},
}
},
select: {
id: true,
name: true,
icon: true,
},
});

// Filter discord guilds where the user does not have MANAGE_GUILD permissions
const filtered_guilds = discord_guilds.filter((guild) => {
return (guild.permissions & (1 << 5)) === 1 << 5 ? guild : false;
});

// Get Discord guilds that are in the database
const included = filtered_guilds.filter((guild) => {
return db_guilds.find((db_guild) => {
return db_guild.id === guild.id;
});
});

// Get Discord guilds that are not in the database
const excluded = filtered_guilds.filter((guild) => {
return !included.find((included_guild) => {
return included_guild.id === guild.id;
});
});

// Return guilds
res.status(200).json({ included, excluded });
};
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading