Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/upload board photo #9

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,6 @@ yarn-error.log*
*.tsbuildinfo
next-env.d.ts

gapi-service-account-creds.json
gapi-service-account-creds.json

.vscode
33 changes: 33 additions & 0 deletions app/api/v1/board/uploadPhoto/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { NextRequest, NextResponse } from "next/server";
import { upload } from "@/util/board";
import { verifyAuthApp } from "@/util";
import { headers } from "next/headers";

export const config = {
api: {
bodyParser: false,
},
};

/**
*
*/
export async function POST(req: NextRequest) {
try {
await verifyAuthApp(headers());
} catch (err: any) {
return NextResponse.json({ error: err }, {status: 400});
}

const form = await req.formData();
const file = form.get('file') as File;
console.log(file);
const url = await upload(file);

return NextResponse.json({ url: url }, {
status: 200,
headers: {
'Content-Type': 'application/json',
},
})
}
17 changes: 17 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@
const nextConfig = {
reactStrictMode: true,
poweredByHeader: false,
experimental: {
appDir: true,
},
async headers() {
return [
{
// matching all API routes
source: "/api/:path*",
headers: [
{ key: "Access-Control-Allow-Credentials", value: "true" },
{ key: "Access-Control-Allow-Origin", value: "*" }, // replace this your actual origin
{ key: "Access-Control-Allow-Methods", value: "GET,DELETE,PATCH,POST,PUT" },
{ key: "Access-Control-Allow-Headers", value: "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" },
]
}
]
}
};

module.exports = nextConfig;
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@
"lint": "next lint"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.588.0",
"@aws-sdk/lib-storage": "^3.609.0",
"@notionhq/client": "^2.2.3",
"@types/node": "18.15.1",
"@types/react": "18.0.28",
"@types/react-dom": "18.0.11",
"aws-sdk": "^2.1633.0",
"discord.js": "^14.8.0",
"eslint": "8.36.0",
"eslint-config-next": "13.2.4",
Expand Down
2 changes: 1 addition & 1 deletion pages/api/v1/acmurl/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
origin: "*",
optionsSuccessStatus: 200,
});

try {
await verifyAuth(req);
} catch (err: any) {
Expand Down
27 changes: 27 additions & 0 deletions src/util/board.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { S3Client } from "@aws-sdk/client-s3";
const path = require('path');
const { Upload } = require("@aws-sdk/lib-storage");

const client = new S3Client({
apiVersion: '2006-03-01',
region: process.env.S3_REGION,
credentials: {
accessKeyId: process.env.S3_ACCESS_KEY_ID,
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY
},
});

export async function upload(file: File) {
const buffer = Buffer.from(await file.arrayBuffer())
const params = {
ACL: 'public-read',
Body: buffer,
Bucket: process.env.S3_BUCKET,
Key: `uploads/${file.name}${path.extname(file.name)}`,
}
const response = await new Upload({
client,
params,
}).done();
return response.Location;
}
17 changes: 16 additions & 1 deletion src/util/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as notion from "./notion";

import totp from "totp-generator";
import { NextApiRequest } from "next";
import { headers } from "next/headers";

const verifyAuth = async (req: NextApiRequest): Promise<void> => {
return new Promise((resolve, reject) => {
Expand All @@ -18,6 +19,20 @@ const verifyAuth = async (req: NextApiRequest): Promise<void> => {
});
};

const verifyAuthApp = async (headerList: Headers): Promise<void> => {
return new Promise((resolve, reject) => {
// console.log(headerList.get("Authorization"));
if (process.env.NODE_ENV !== "production") resolve();
const authToken = headerList.get("Authorization");
if (!authToken) {
reject("Missing auth token");
} else if (!validateAuthToken(authToken)) {
reject("Invalid auth token");
}
resolve();
});
};

/**
* Use our TOTP key to validate the rotating bearer token is valid to ensure the client has the secret key that changes every 10 seconds
* @param token
Expand All @@ -38,4 +53,4 @@ const validateAuthToken = (token: string) => {
return accessToken === totpValue;
};

export { discord, calendar, notion, verifyAuth };
export { discord, calendar, notion, verifyAuth, verifyAuthApp };
28 changes: 23 additions & 5 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
Expand All @@ -15,9 +19,23 @@
"jsx": "preserve",
"incremental": true,
"paths": {
"@/*": ["./src/*"]
}
"@/*": [
"./src/*"
]
},
"plugins": [
{
"name": "next"
}
]
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts"
],
"exclude": [
"node_modules"
]
}
Loading