config husky

This commit is contained in:
Jyotirmoy Bandyopadhayaya 2023-04-20 13:46:57 +05:30
parent 2544ce8031
commit 34e2a94fce
Signed by: bravo68web
GPG Key ID: F5671FD7BCB9917A
13 changed files with 79 additions and 73 deletions

View File

@ -1,9 +1,9 @@
import { authClient } from "../helpers/auth_client";
import { generators } from 'openid-client';
import { configKeys } from "..";
import { authClient } from '../helpers/auth_client'
import { generators } from 'openid-client'
import { configKeys } from '..'
const code_verifier = generators.codeVerifier();
const code_challenge = generators.codeChallenge(code_verifier);
const code_verifier = generators.codeVerifier()
const code_challenge = generators.codeChallenge(code_verifier)
export default () => {
const authurl = authClient.authorizationUrl({
@ -12,14 +12,11 @@ export default () => {
code_challenge_method: 'S256',
client_id: configKeys.KEYCLOAK_CLIENT_ID,
redirect_uri: configKeys.KEYCLOAK_REDIRECT_URI,
});
})
return {
authurl,
};
}
}
export {
code_challenge,
code_verifier,
}
export { code_challenge, code_verifier }

View File

@ -1,32 +1,37 @@
import { NextFunction, Response } from "express";
import {authClient} from "../helpers/auth_client";
import { ModRequest } from "../types";
import { CustomError } from "../libs/error";
import { NextFunction, Response } from 'express'
import { authClient } from '../helpers/auth_client'
import { ModRequest } from '../types'
import { CustomError } from '../libs/error'
const middleware = async (req: ModRequest | any, res: Response, next: NextFunction) => {
const middleware = async (
req: ModRequest | any,
res: Response,
next: NextFunction
) => {
try {
const authHeader = req.headers?.authorization?.split(' ');
const authHeader = req.headers?.authorization?.split(' ')
if (!authHeader) {
throw new Error("No authorization header");
throw new Error('No authorization header')
}
const token : string = authHeader[1];
const token: string = authHeader[1]
const user = await authClient.userinfo(token, {
method: 'GET',
tokenType: 'Bearer',
params: {
access_token: token
access_token: token,
},
via: 'header'
});
req.user = user;
next();
}
catch (err) {
next(new CustomError({
message: "Invalid token",
statusCode: 401
}))
via: 'header',
})
req.user = user
next()
} catch (err) {
next(
new CustomError({
message: 'Invalid token',
statusCode: 401,
})
)
}
}
export default middleware
export default middleware

View File

@ -1,10 +1,10 @@
import {authClient} from "../helpers/auth_client";
import { authClient } from '../helpers/auth_client'
import { code_verifier } from './check'
export default async (session_state: string, code: string) => {
return authClient.callback(
'http://localhost:4038/auth/signin/callback',
{ code_verifier, code, session_state, expires_in: "1d" },
{ code_verifier, code, session_state, expires_in: '1d' },
{ code_verifier }
);
}
)
}

View File

@ -1,9 +1,11 @@
import fs from 'fs'
import { parse as parseFile } from 'envfile'
import { Issuer } from 'openid-client';
import { Issuer } from 'openid-client'
const keyCloakIssuer : Issuer = await Issuer.discover(process.env.KEYCLOAK_AUTH_SERVER_URL!);
console.log('🔐 Connected to Keycloak');
const keyCloakIssuer: Issuer = await Issuer.discover(
process.env.KEYCLOAK_AUTH_SERVER_URL!
)
console.log('🔐 Connected to Keycloak')
type IconfigStore = 'development' | 'production'
@ -48,7 +50,7 @@ export interface IConfigKeys {
export default class ConfigStoreFactory {
public configStoreType: IconfigStore
constructor(isProd: boolean = false) {
constructor(isProd = false) {
if (isProd) {
this.configStoreType = 'production'
} else {
@ -57,8 +59,8 @@ export default class ConfigStoreFactory {
}
public async getConfigStore() {
const publicKEY = fs.readFileSync('./jwtRS256.key', 'utf8');
const privateKEY = fs.readFileSync('./jwtRS256.key.pub', 'utf8');
const publicKEY = fs.readFileSync('./jwtRS256.key', 'utf8')
const privateKEY = fs.readFileSync('./jwtRS256.key.pub', 'utf8')
if (this.configStoreType === 'development') {
const envContent = await fs.readFileSync(`./.env`, 'utf8')
const env: Partial<IConfigKeys> = await parseFile(envContent)
@ -73,8 +75,8 @@ export default class ConfigStoreFactory {
)
reqEnvContent = reqEnvContent.replaceAll('=', '')
reqEnvContent = reqEnvContent.split('\n')
let missingKeys: string[] = []
let env: Partial<IConfigKeys> = {}
const missingKeys: string[] = []
const env: Partial<IConfigKeys> = {}
env.PUBLIC_KEY = publicKEY
env.PRIVATE_KEY = privateKEY
env.KEYCLOAK_ISSUER = keyCloakIssuer

View File

@ -11,11 +11,14 @@ export default class AuthController {
}
public callback = async (req: Request, res: Response) => {
const { session_state, code } = req.query as { session_state: string, code: string}
const { session_state, code } = req.query as {
session_state: string
code: string
}
res.send(makeResponse(await verify(session_state, code)))
}
public me = (req: ModRequest, res: Response) => {
res.send(makeResponse(req.user))
}
}
}

View File

@ -4,11 +4,10 @@ import { Request, Response } from 'express'
export default class MastodonController extends MastodonService {
public fetchMastodonProfile = async (req: Request, res: Response) => {
try{
try {
const data = await this.getMastodonProfile()
return res.send(makeResponse(data))
}
catch (err: any){
} catch (err: any) {
res.send(makeResponse(err.message, {}, 'Failed', true))
}
}
@ -17,8 +16,7 @@ export default class MastodonController extends MastodonService {
try {
const data = await this.getMastodonStatuses()
return res.send(makeResponse(data))
}
catch (err: any) {
} catch (err: any) {
res.send(makeResponse(err.message, {}, 'Failed', true))
}
}

View File

@ -1,4 +1,4 @@
import { configKeys } from "..";
import { configKeys } from '..'
const { KEYCLOAK_ISSUER } = configKeys
@ -7,7 +7,9 @@ const authConfig = {
'auth-server-url': configKeys.KEYCLOAK_AUTH_SERVER_URL,
'ssl-required': 'all',
resource: configKeys.KEYCLOAK_CLIENT_ID,
credentials: { 'secret-jwt': { secret: configKeys.KEYCLOAK_CLIENT_SECRET } },
credentials: {
'secret-jwt': { secret: configKeys.KEYCLOAK_CLIENT_SECRET },
},
'confidential-port': 0,
redirect_uri: configKeys.KEYCLOAK_REDIRECT_URI,
client_secret: configKeys.KEYCLOAK_CLIENT_SECRET,
@ -16,4 +18,4 @@ const authConfig = {
const authClient = new KEYCLOAK_ISSUER.Client(authConfig)
export { authClient }
export { authClient }

View File

@ -5,30 +5,30 @@ import morgan from 'morgan'
import helmet from 'helmet'
import { hgqlInit } from './helpers'
import cacheClient from './helpers/cache.factory';
import cacheClient from './helpers/cache.factory'
import routes from './routes'
import { errorHandler, notFoundHandler } from './libs'
import pkg from './package.json' assert { type: 'json' }
import configStore, { IConfigKeys } from './configs';
import configStore, { IConfigKeys } from './configs'
export const app: express.Application = express()
console.log('🚀', '@b68/api', 'v' + pkg.version)
hgqlInit()
cacheClient.init();
cacheClient.init()
const isDev: boolean = process.env.NODE_ENV == 'production'
console.log(isDev ? '🚀 Production Mode' : '👷 Development Mode')
const configs = new configStore(isDev)
const configKeys: IConfigKeys = await configs.getConfigStore() as IConfigKeys
const configKeys: IConfigKeys = (await configs.getConfigStore()) as IConfigKeys
app.use(cors())
app.use(helmet())
app.use(morgan('dev'))
app.use(express.json())
app.use(express.urlencoded({ extended: true, limit: '50mb' }))
app.set('view engine', 'ejs');
app.set('view engine', 'ejs')
console.log('☄ ', 'Base Route', '/')

View File

@ -11,8 +11,8 @@ router.get('/signin/callback', authController.callback)
router.get('/me', middleware, authController.me as any)
router.get('/', function(req, res) {
res.render('pages/auth');
});
router.get('/', function (req, res) {
res.render('pages/auth')
})
export default router

View File

@ -2,11 +2,10 @@ import { Router } from 'express'
const router = Router()
router.use('/health',
(req, res) => {
router.use('/health', (req, res) => {
return res.status(200).json({
status: "OK",
app: "B68 API",
status: 'OK',
app: 'B68 API',
request_ip: req.ip,
uptime: process.uptime(),
hrtime: process.hrtime(),

View File

@ -49,12 +49,12 @@ baseDir = path.resolve(baseDir)
loadRoutes(baseDir)
router.get('/', function(req, res) {
res.render('pages/index');
});
router.get('/', function (req, res) {
res.render('pages/index')
})
router.get('/favicon.ico', function(req, res) {
res.sendFile(path.join(__dirname, '../public', 'favicon.ico'));
});
router.get('/favicon.ico', function (req, res) {
res.sendFile(path.join(__dirname, '../public', 'favicon.ico'))
})
export default router

View File

@ -12,7 +12,7 @@ export default class MastodonService {
const { data } = await axiosInstance.get(
'https://fosstodon.org/api/v1/accounts/109612266657666903/statuses',
{
timeout: 10000
timeout: 10000,
}
)
return data

View File

@ -10,4 +10,4 @@ export interface PaginationType {
export interface ModRequest extends Request {
user: any
}
}