Skip to content

Commit

Permalink
chore: wip
Browse files Browse the repository at this point in the history
  • Loading branch information
wajeht committed Sep 22, 2024
1 parent febe4c5 commit 3276c73
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 53 deletions.
36 changes: 24 additions & 12 deletions public/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ html,
-moz-tab-size: 4;
/* 3 */
-o-tab-size: 4;
tab-size: 4;
tab-size: 4;
/* 3 */
font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-family: ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
'Segoe UI Symbol', 'Noto Color Emoji';
/* 4 */
font-feature-settings: normal;
/* 5 */
Expand Down Expand Up @@ -89,7 +90,7 @@ Add the correct text decoration in Chrome, Edge, and Safari.

abbr:where([title]) {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
text-decoration: underline dotted;
}

/*
Expand Down Expand Up @@ -135,7 +136,8 @@ code,
kbd,
samp,
pre {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono',
'Courier New', monospace;
/* 1 */
font-feature-settings: normal;
/* 2 */
Expand Down Expand Up @@ -378,7 +380,8 @@ textarea {
2. Set the default placeholder color to the user's configured gray 400 color.
*/

input::-moz-placeholder, textarea::-moz-placeholder {
input::-moz-placeholder,
textarea::-moz-placeholder {
opacity: 1;
/* 1 */
color: #9ca3af;
Expand All @@ -398,7 +401,7 @@ Set the default cursor for buttons.
*/

button,
[role="button"] {
[role='button'] {
cursor: pointer;
}

Expand Down Expand Up @@ -446,7 +449,9 @@ video {
display: none;
}

*, ::before, ::after {
*,
::before,
::after {
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
Expand Down Expand Up @@ -731,12 +736,14 @@ video {
}

.transform {
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) !important;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
scaleY(var(--tw-scale-y)) !important;
}

@keyframes pulse {
50% {
opacity: .5;
opacity: 0.5;
}
}

Expand Down Expand Up @@ -1067,8 +1074,13 @@ video {

.backdrop-blur-sm {
--tw-backdrop-blur: blur(4px) !important;
-webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia) !important;
backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia) !important;
-webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness)
var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate)
var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate)
var(--tw-backdrop-sepia) !important;
backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast)
var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert)
var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia) !important;
}

* {
Expand Down Expand Up @@ -1131,7 +1143,7 @@ html {
}

.hover\:outline-\[\#1A8755\]:hover {
outline-color: #1A8755 !important;
outline-color: #1a8755 !important;
}

.hover\:outline-slate-50:hover {
Expand Down
2 changes: 1 addition & 1 deletion src/api/records/records.services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export async function getRecords({ cache = true }: getRecordsType) {

for (const e of h2) {
data.push({
title: e.children[0].innerHTML,
title: e.children[0]!.innerHTML,
records: tableToJson(e.children[1]),
});
}
Expand Down
16 changes: 8 additions & 8 deletions src/app.middlewares.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { beforeEach, describe, expect, test, vi } from 'vitest';
import { ZodError } from 'zod';
import { ZodIssue, ZodIssueCode } from 'zod';

import { handleHostname, notFoundHandler, validate } from './app.middlewares';
import { hostNameMiddleware, notFoundMiddleware, validationMiddleware } from './app.middlewares';
import { getHostName } from './utils/helpers';
import * as utils from './utils/helpers';
import redis from './utils/redis';
Expand Down Expand Up @@ -33,7 +33,7 @@ describe('notFoundHandler', () => {

test('renders "not-found.html" if the URL does not start with "/api/"', () => {
req.url = '/some-url';
notFoundHandler(req, res, next);
notFoundMiddleware(req, res, next);

expect(res.status).toHaveBeenCalledWith(StatusCodes.NOT_FOUND);
expect(res.render).toHaveBeenCalledWith('not-found.html');
Expand All @@ -44,7 +44,7 @@ describe('notFoundHandler', () => {
test('returns a JSON response if the URL starts with "/api/"', () => {
req.url = '/api/some-url';
req.originalUrl = '/api/some-url';
notFoundHandler(req, res, next);
notFoundMiddleware(req, res, next);

expect(res.status).toHaveBeenCalledWith(StatusCodes.NOT_FOUND);
expect(res.json).toHaveBeenCalledWith({
Expand Down Expand Up @@ -91,7 +91,7 @@ describe('validate', () => {
test('successfully validates and calls next if no errors', async () => {
validators.body.parseAsync.mockResolvedValue({ foo: 'bar' });

const middleware = validate(validators);
const middleware = validationMiddleware(validators);
await middleware(req, res, next);

expect(req.body).toEqual({ foo: 'bar' });
Expand All @@ -112,7 +112,7 @@ describe('validate', () => {

validators.body.parseAsync.mockRejectedValue(error);

const middleware = validate(validators);
const middleware = validationMiddleware(validators);
await middleware(req, res, next);

expect(req.flash).toHaveBeenCalledWith('error', errorMessage);
Expand All @@ -125,7 +125,7 @@ describe('validate', () => {
const error = new Error('Something bad happened');
validators.body.parseAsync.mockRejectedValue(error);

const middleware = validate(validators);
const middleware = validationMiddleware(validators);
await middleware(req, res, next);

expect(next).toHaveBeenCalledWith(error);
Expand Down Expand Up @@ -163,7 +163,7 @@ describe('handleHostname', () => {
// @ts-ignore
redis.get.mockResolvedValue(mockHostname);

await handleHostname(req, res, next);
await hostNameMiddleware(req, res, next);

// @ts-ignore
expect(redis.get).toHaveBeenCalledWith('hostname');
Expand All @@ -184,7 +184,7 @@ describe('handleHostname', () => {

req.get.mockReturnValue('localhost');

await handleHostname(req, res, next);
await hostNameMiddleware(req, res, next);

// @ts-ignore
expect(redis.get).toHaveBeenCalledWith('hostname');
Expand Down
4 changes: 2 additions & 2 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
} from './app.middlewares';
import swaggerConfig from './config/swagger.config';
import viewsRoutes from './views/views.routes';
import { ENV } from 'config/constants';
import { appConfig } from 'config/constants';

const app = express();

Expand Down Expand Up @@ -55,7 +55,7 @@ app.set('views', path.resolve(path.join(process.cwd(), 'src', 'views', 'pages'))

app.set('layout', path.resolve(path.join(process.cwd(), 'src', 'views', 'layouts', 'main.html')));

app.set('view cache', ENV === 'production');
app.set('view cache', appConfig.env === 'production');

app.use(expressLayouts);

Expand Down
36 changes: 18 additions & 18 deletions src/utils/admin-user.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { faker } from '@faker-js/faker';
import bcrypt from 'bcryptjs';
import { afterEach, describe, expect, it, test, vi } from 'vitest';
import { afterEach, describe, expect, it, Mock, test, vi } from 'vitest';

import { ADMIN, EMAIL, PASSWORD_SALT } from '../config/constants';
import { emailConfig, appConfig } from '../config/constants';
import { generateAPIKey, hashKey, updateUser } from '../utils/helpers';
import mail from '../utils/mail';
import { User } from '../views/views.models';
Expand Down Expand Up @@ -62,37 +62,37 @@ describe('init', () => {
});

it('should create a new admin user if one does not exist', async () => {
User.findOne.mockResolvedValueOnce(null);
(User.findOne as Mock).mockResolvedValueOnce(null);

faker.internet.password.mockReturnValueOnce('password');
(faker.internet.password as Mock).mockReturnValueOnce('password');

// bcrypt.hash.mockResolvedValueOnce('hashedPassword');

await hashKey.mockResolvedValueOnce({ key: 'token' });
((await hashKey) as Mock).mockResolvedValueOnce({ key: 'token' });

User.create.mockResolvedValueOnce({
name: ADMIN.NAME,
(User.create as Mock).mockResolvedValueOnce({
name: appConfig.admin_name,
id: 'adminId',
email: ADMIN.EMAIL,
email: appConfig.admin_email,
});

await generateAPIKey.mockResolvedValueOnce({
((await generateAPIKey) as Mock).mockResolvedValueOnce({
hashedKey: 'hashedKey',
unhashedKey: 'unhashedKey',
});

updateUser.mockResolvedValueOnce({ name: ADMIN.NAME });
updateUser.mockResolvedValueOnce({ name: appConfig.admin_email });

mail.sendMail = vi.fn().mockResolvedValue({});

await init();

expect(User.findOne).toHaveBeenCalledWith({ email: ADMIN.EMAIL });
expect(User.findOne).toHaveBeenCalledWith({ email: appConfig.admin_email });
expect(faker.internet.password).toHaveBeenCalledWith(50);
// expect(bcrypt.hash).toHaveBeenCalledWith('password', parseInt(PASSWORD_SALT!));
expect(User.create).toHaveBeenCalledWith({
email: ADMIN.EMAIL,
name: ADMIN.NAME,
email: appConfig.admin_email,
name: appConfig.admin_name,
admin: true,
password: expect.any(String),
verification_token: expect.any(String),
Expand All @@ -102,9 +102,9 @@ describe('init', () => {

expect(generateAPIKey).toHaveBeenCalledWith({
admin: true,
name: ADMIN.NAME,
name: appConfig.admin_name,
userId: 'adminId',
email: ADMIN.EMAIL,
email: appConfig.admin_email,
});

// expect(updateUser).toHaveBeenCalledWith(ADMIN.EMAIL, { key: 'hashedKey' });
Expand All @@ -118,16 +118,16 @@ describe('init', () => {
});

it('should not create a new admin user if one exists', async () => {
User.findOne.mockResolvedValueOnce({ id: 'existingAdminId' });
(User.findOne as Mock).mockResolvedValueOnce({ id: 'existingAdminId' });

await init();

expect(User.findOne).toHaveBeenCalledWith({ email: ADMIN.EMAIL });
expect(User.findOne).toHaveBeenCalledWith({ email: appConfig.admin_email });
expect(User.create).not.toHaveBeenCalled();
});

it('should log an error if anything goes wrong', async () => {
User.findOne.mockRejectedValueOnce(new Error('Error message'));
(User.findOne as Mock).mockRejectedValueOnce(new Error('Error message'));
const errorSpy = vi.spyOn(logger, 'error');

await init();
Expand Down
23 changes: 11 additions & 12 deletions src/utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import crypto from 'crypto';
import { Request } from 'express';
import jwt from 'jsonwebtoken';

import { DOMAIN, ENV, JWT_SECRET, PASSWORD_SALT } from '../config/constants';
import { OAUTH } from '../config/constants';
import { oauthConfig, appConfig } from '../config/constants';
import { UserParams } from '../views/views.services';

type buildPaginationType = {
Expand Down Expand Up @@ -50,12 +49,12 @@ export function stripHTML(innerHTML: string): string {
export function getHostName(req: Request): string {
let origin = '';

if (ENV === 'development') {
if (appConfig.env === 'development') {
const protocol = req.protocol;
const hostname = req.get('host');
origin = `${protocol}://${hostname}`;
} else {
origin = DOMAIN!;
origin = appConfig.domain!;
}

return origin;
Expand All @@ -80,16 +79,16 @@ export async function generateAPIKey(userParams: UserParams & { admin?: boolean
};

if (admin) {
const key = jwt.sign(keyOptions, JWT_SECRET!);
const key = jwt.sign(keyOptions, appConfig.jwt_secret);
return {
unhashedKey: key,
hashedKey: await bcrypt.hash(key, parseInt(PASSWORD_SALT!)),
hashedKey: await bcrypt.hash(key, parseInt(appConfig.password_salt)),
};
} else {
const key = jwt.sign(keyOptions, JWT_SECRET!, { expiresIn: '3m' });
const key = jwt.sign(keyOptions, appConfig.jwt_secret, { expiresIn: '3m' });
return {
unhashedKey: key,
hashedKey: await bcrypt.hash(key, parseInt(PASSWORD_SALT!)),
hashedKey: await bcrypt.hash(key, parseInt(appConfig.password_salt)),
};
}
}
Expand All @@ -98,8 +97,8 @@ export function getGoogleOAuthURL() {
const rootUrl = 'https://accounts.google.com/o/oauth2/v2/auth';

const options = {
redirect_uri: OAUTH.GOOGLE.OAUTH_REDIRECT_URL,
client_id: OAUTH.GOOGLE.CLIENT_ID,
redirect_uri: oauthConfig.google.oauth_redirect_url,
client_id: oauthConfig.github.client_id,
access_type: 'offline',
response_type: 'code',
prompt: 'consent',
Expand All @@ -118,8 +117,8 @@ export function getGitHubOAuthURL() {
const rootUrl = 'https://github.com/login/oauth/authorize';

const options = {
redirect_uri: OAUTH.GITHUB.OAUTH_REDIRECT_URL,
client_id: OAUTH.GITHUB.CLIENT_ID,
redirect_uri: oauthConfig.google.oauth_redirect_url,
client_id: oauthConfig.github.client_id,
scope: 'user:email',
};

Expand Down

0 comments on commit 3276c73

Please sign in to comment.