Skip to content

Commit

Permalink
convert API routes to TS
Browse files Browse the repository at this point in the history
  • Loading branch information
thorinaboenke committed Nov 26, 2020
1 parent a340a22 commit bf6738f
Show file tree
Hide file tree
Showing 16 changed files with 126 additions and 163 deletions.
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"cSpell.words": [
"geoquiz"
]
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@emotion/core": "^10.0.35",
"@emotion/styled": "^10.0.27",
"@types/nodemailer": "^6.4.0",
"@types/nodemailer-mailgun-transport": "^1.4.2",
"argon2": "^0.27.0",
"camelcase-keys": "^6.2.2",
"cloudinary": "^1.23.0",
Expand All @@ -31,7 +32,7 @@
"next-cookies": "^2.0.3",
"nodemailer": "^6.4.16",
"nodemailer-mailgun-transport": "^2.0.1",
"postgres": "^1.0.2",
"postgres": "2.0.0-beta.2",
"react": "17.0.0",
"react-dom": "17.0.0",
"react-dom-confetti": "^0.2.0",
Expand Down
8 changes: 6 additions & 2 deletions pages/api/avatar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,18 @@ export default async function handler(
request: NextApiRequest,
response: NextApiResponse,
) {
const { data, userId, token, username } = request.body;
const { data, userId, username } = request.body;
const options: UploadApiOptions = { public_id: username, folder: 'geoquiz' };
const cloudinaryResponse = await cloudinary.uploader.upload(
data,
options,
function (error: UploadApiErrorResponse, result: UploadApiResponse) {
try {
insertAvatarUrlByUserId(userId, result.secure_url, token);
insertAvatarUrlByUserId(
userId,
result.secure_url,
request.cookies.session,
);
return response
.status(200)
.send({ success: true, newUrl: result.secure_url });
Expand Down
4 changes: 2 additions & 2 deletions pages/api/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ export default async function handler(
request: NextApiRequest,
response: NextApiResponse,
) {
const { userId, avatarUrl, token } = request.body;
const { userId, avatarUrl } = request.body;
try {
await insertAvatarUrlByUserId(userId, avatarUrl, token);
await insertAvatarUrlByUserId(userId, avatarUrl, request.cookies.session);
} catch (err) {
console.error('Avatar could not be updated');
return response.status(500).send({ success: false });
Expand Down
2 changes: 1 addition & 1 deletion pages/contact.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,6 @@ export async function getServerSideProps(context) {
token = null;
}
return {
props: { loggedIn: loggedIn, user: user, token: token },
props: { loggedIn: loggedIn, user: user },
};
}
10 changes: 4 additions & 6 deletions pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ export default function Home(props) {
score,
categoryAnswer,
region,
props.token,
);
}
if (displayQuestion === questions.length && score === questions.length)
Expand All @@ -122,7 +121,6 @@ export default function Home(props) {
score,
categoryAnswer,
region,
props.token,
]);

const handleAnswerClick = (correct, answerArray, answer) => {
Expand Down Expand Up @@ -548,12 +546,12 @@ export default function Home(props) {
}

export async function getServerSideProps(context) {
let { session: token } = nextCookies(context) ;
const loggedIn = await isSessionTokenValid(token);
const user = (await getUserBySessionToken(token));
let { session: token } = nextCookies(context);
const loggedIn = (await isSessionTokenValid(token)) || null;
const user = (await getUserBySessionToken(token)) || null;
if (typeof token === 'undefined') {
token = null;
}
console.log({ user });
return { props: { loggedIn: loggedIn, user: user, token: token } };
return { props: { loggedIn: loggedIn, user: user } };
}
2 changes: 1 addition & 1 deletion pages/memory.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,6 @@ export async function getServerSideProps(context) {
token = null;
}
return {
props: { loggedIn: loggedIn, user: user, token: token },
props: { loggedIn: loggedIn, user: user},
};
}
9 changes: 3 additions & 6 deletions pages/profile.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ function getResizedCanvas(canvas, newWidth, newHeight) {
}

function Profile(props) {
const { user, loggedIn, token } = props;
const { user, loggedIn } = props;
const [imageUrl, setImageUrl] = useState(props.user.avatarUrl);
const [upImg, setUpImg] = useState(null);
const previewCanvasRef = useRef(null);
Expand All @@ -191,8 +191,8 @@ function Profile(props) {
const fileUploadHandler = async (canvas) => {
var dataURL = canvas.toDataURL();
setIsLoading(true);
postPicture(dataURL, user.userId, token);
async function postPicture(data, userId, sessiontoken) {
postPicture(dataURL, user.userId);
async function postPicture(data, userId) {
const response = await fetch('/api/avatar', {
method: 'POST',
headers: {
Expand All @@ -201,7 +201,6 @@ function Profile(props) {
body: JSON.stringify({
data: data,
userId: userId,
token: sessiontoken,
username: user.username,
}),
});
Expand Down Expand Up @@ -376,7 +375,6 @@ function Profile(props) {
},
body: JSON.stringify({
username: user.username,
token: token,
}),
});
const { success } = await response.json();
Expand Down Expand Up @@ -406,7 +404,6 @@ export async function getServerSideProps(context) {
scores: scores,
user: user,
loggedIn: true,
token: token,
},
};
}
Expand Down
1 change: 0 additions & 1 deletion pages/signup.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ export default function Signup(props) {
body: JSON.stringify({
username: username,
password: password,
token: props.token,
}),
});

Expand Down
2 changes: 1 addition & 1 deletion util/auth.js → util/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { getSessionByToken } from './database';
// 1) check if there is a token
// 2) check if there is a session for that token in the database
// 3) check if the session is expired
export async function isSessionTokenValid(token) {
export async function isSessionTokenValid(token: string) {
if (typeof token === 'undefined') {
return false;
}
Expand Down
File renamed without changes.
58 changes: 32 additions & 26 deletions util/database.js → util/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import postgres from 'postgres';
import dotenv from 'dotenv';
import camelcaseKeys from 'camelcase-keys';
import extractHerokuDatabaseEnvVars from './extractHerokuDatabaseEnvVars';
import { User, Session, Category, Region } from './types';

extractHerokuDatabaseEnvVars();
dotenv.config();
Expand All @@ -14,15 +15,15 @@ const sql =
postgres({ ssl: { rejectUnauthorized: false } })
: postgres({ idle_timeout: 5 });

export async function getUserByUsername(username) {
export async function getUserByUsername(username: string) {
const users = await sql`
SELECT * FROM users WHERE username = ${username};
`;

return users.map((u) => camelcaseKeys(u))[0];
return users.map((u: User) => camelcaseKeys(u))[0];
}

export async function registerUser(username, passwordHash) {
export async function registerUser(username: string, passwordHash: string) {
// insert the user in the user table
const users = await sql`
INSERT INTO users
Expand All @@ -32,9 +33,10 @@ export async function registerUser(username, passwordHash) {
RETURNING *;
`;
// get the existing category ids
const categoryIds = await sql`
const categoryIds: Category[] = await sql`
SELECT category_id FROM categories;
`;
console.log({ categoryIds });
const categoryArray = categoryIds.map((entry) => entry.category_id);
// insert a row with 0 values for each category for the new user
for (const id of categoryArray) {
Expand All @@ -49,7 +51,7 @@ export async function registerUser(username, passwordHash) {
);`;
}
// get the existing region ids
const regionIds = await sql`
const regionIds: Region[] = await sql`
SELECT region_id FROM regions;
`;
// insert a row with 0 values for each region for the new user
Expand All @@ -66,10 +68,10 @@ export async function registerUser(username, passwordHash) {
);`;
}

return users.map((u) => camelcaseKeys(u))[0];
return users.map((u: User) => camelcaseKeys(u))[0];
}

export async function insertSession(token, userId) {
export async function insertSession(token: string, userId: number) {
const sessions = await sql`
INSERT INTO sessions
(token, user_id)
Expand All @@ -78,25 +80,25 @@ export async function insertSession(token, userId) {
RETURNING *;
`;

return sessions.map((u) => camelcaseKeys(u))[0];
return sessions.map((s: Session) => camelcaseKeys(s))[0];
}

export async function getSessionByToken(token) {
export async function getSessionByToken(token: string) {
const sessions = await sql`
SELECT FROM sessions WHERE token = ${token};
`;
return sessions.map((u) => camelcaseKeys(u))[0];
return sessions.map((s: Session) => camelcaseKeys(s))[0];
}

export async function deleteSessionByToken(token) {
export async function deleteSessionByToken(token: string) {
await sql`DELETE FROM sessions WHERE token = ${token};`;
}

export async function deleteExpiredSessions() {
await sql`DELETE FROM sessions WHERE expiry_timestamp < NOW();`;
}

export async function getUserBySessionToken(token) {
export async function getUserBySessionToken(token: string) {
const users = await sql`SELECT
users.user_id, users.username, users.total_answered_questions, users.total_correct_questions, users.streak_days, users.avatar_url
FROM
Expand All @@ -107,10 +109,10 @@ export async function getUserBySessionToken(token) {
sessions.user_id = users.user_id
;`;

return users.map((u) => camelcaseKeys(u))[0];
return users.map((u: User) => camelcaseKeys(u))[0];
}

export async function getScoresBySessionToken(token) {
export async function getScoresBySessionToken(token: string) {
const cat = await sql`
SELECT
category_scores.answered_questions as cat_answered,
Expand Down Expand Up @@ -147,7 +149,7 @@ WHERE users.user_id = (SELECT
sessions.token = ${token} AND
sessions.user_id = users.user_id);`;

const categoryScores = cat.map((u) => camelcaseKeys(u));
const categoryScores = cat.map((scores) => camelcaseKeys(scores));

const reducedCategoryScores = categoryScores.reduce((acc, curr) => {
acc[curr.category] = {
Expand All @@ -172,21 +174,21 @@ WHERE users.user_id = (SELECT
return scores;
}

export async function deleteUserByUsername(username, token) {
export async function deleteUserByUsername(username: string, token: string) {
const users = await sql`
DELETE FROM users where username = ${username} AND user_id = (SELECT user_id FROM sessions WHERE
sessions.token = ${token} )
Returning *;`;
return users.map((u) => camelcaseKeys(u))[0];
return users.map((u: User) => camelcaseKeys(u))[0];
}

export async function updateScoresByUserId(
userId,
answeredQuestions,
correctQuestions,
categoryAnswer,
region,
token,
userId: number,
answeredQuestions: number,
correctQuestions: number,
categoryAnswer: number,
region: string,
token: string,
) {
// update the total score, total questions, last_game_played and streak_days in the user table
if (userId) {
Expand Down Expand Up @@ -225,11 +227,15 @@ export async function getTopTen() {
SELECT username,total_correct_questions, avatar_url FROM users ORDER BY total_correct_questions DESC LIMIT 10;
`;

return users.map((u) => camelcaseKeys(u));
return users.map((u: Partial<User>) => camelcaseKeys(u));
}

export async function insertAvatarUrlByUserId(userId, url, token) {
const avatarUrl = await sql`
export async function insertAvatarUrlByUserId(
userId: number,
url: string,
token: string,
) {
await sql`
UPDATE users
SET avatar_url = ${url}
WHERE user_id = (SELECT user_id FROM sessions WHERE
Expand Down
Loading

0 comments on commit bf6738f

Please sign in to comment.