-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 6633e19
Showing
17 changed files
with
6,893 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
TARGET_HOST=api.yourservice.com | ||
USER_FIELD=email |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
dist | ||
node_modules | ||
.env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
{ | ||
"root": true, | ||
"extends": [ | ||
"eslint:recommended", | ||
"plugin:n/recommended", | ||
"airbnb-base", | ||
"plugin:@typescript-eslint/recommended", | ||
"plugin:@typescript-eslint/recommended-requiring-type-checking", | ||
"airbnb-typescript/base", | ||
"plugin:prettier/recommended" | ||
], | ||
"parserOptions": { | ||
"project": ["./tsconfig.json"], | ||
"ecmaVersion": 2022, | ||
"sourceType": "module" | ||
}, | ||
"env": { | ||
"node": true | ||
}, | ||
"rules": { | ||
"import/prefer-default-export": "off", | ||
"node/no-missing-import": "off", | ||
"@typescript-eslint/return-await": ["error", "always"], | ||
"@typescript-eslint/member-ordering": ["error"], | ||
"@typescript-eslint/no-empty-function": ["error", { "allow": ["private-constructors"] }], | ||
"@typescript-eslint/array-type": ["error", { "default": "array-simple", "readonly": "array-simple" }] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
coverage: | ||
status: | ||
project: | ||
default: | ||
informational: true | ||
patch: | ||
default: | ||
informational: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"$schema": "https://docs.renovatebot.com/renovate-schema.json", | ||
"extends": ["config:base"], | ||
"assigneesFromCodeOwners": true, | ||
"reviewersFromCodeOwners": true, | ||
"labels": ["dependencies"], | ||
"major": { | ||
"dependencyDashboardApproval": false | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
name: CI | ||
|
||
on: | ||
push: | ||
branches: | ||
- master | ||
pull_request: | ||
branches: | ||
- '**' | ||
|
||
concurrency: | ||
group: ${{ github.ref }} | ||
cancel-in-progress: false | ||
|
||
jobs: | ||
install: | ||
runs-on: ubuntu-22.04 | ||
steps: | ||
- uses: actions/checkout@v3 | ||
|
||
- uses: actions/setup-node@v3 | ||
with: | ||
node-version: lts/* | ||
cache: "yarn" | ||
|
||
- name: Restore node_modules | ||
uses: actions/cache@v3 | ||
with: | ||
path: node_modules | ||
key: ${{ runner.os }}-${{ hashFiles('yarn.lock') }} | ||
|
||
- run: yarn install --immutable | ||
|
||
lint: | ||
needs: [install] | ||
runs-on: ubuntu-22.04 | ||
steps: | ||
- uses: actions/checkout@v3 | ||
|
||
- uses: actions/setup-node@v3 | ||
with: | ||
node-version: lts/* | ||
cache: "yarn" | ||
|
||
- name: Restore node_modules | ||
uses: actions/cache@v3 | ||
with: | ||
path: node_modules | ||
key: ${{ runner.os }}-${{ hashFiles('yarn.lock') }} | ||
|
||
- run: yarn lint | ||
|
||
build: | ||
needs: [install] | ||
runs-on: ubuntu-22.04 | ||
steps: | ||
- uses: actions/checkout@v3 | ||
|
||
- uses: actions/setup-node@v3 | ||
with: | ||
node-version: lts/* | ||
cache: "yarn" | ||
|
||
- name: Restore node_modules | ||
uses: actions/cache@v3 | ||
with: | ||
path: node_modules | ||
key: ${{ runner.os }}-${{ hashFiles('yarn.lock') }} | ||
|
||
- run: yarn build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
dist | ||
node_modules | ||
.env | ||
|
||
# https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored | ||
.pnp.* | ||
.yarn/* | ||
!.yarn/patches | ||
!.yarn/plugins | ||
!.yarn/releases | ||
!.yarn/sdks | ||
!.yarn/versions |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"tabWidth": 2, | ||
"useTabs": false, | ||
"semi": true, | ||
"singleQuote": true, | ||
"trailingComma": "all", | ||
"printWidth": 120, | ||
"arrowParens": "avoid", | ||
"endOfLine": "lf" | ||
} |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
enableGlobalCache: true | ||
|
||
nodeLinker: node-modules | ||
|
||
yarnPath: .yarn/releases/yarn-3.5.0.cjs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"$schema": "https://json.schemastore.org/nest-cli", | ||
"collection": "@nestjs/schematics", | ||
"sourceRoot": "src" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
{ | ||
"name": "hydra-proxy", | ||
"version": "1.0.0", | ||
"main": "index.js", | ||
"type": "module", | ||
"license": "MIT", | ||
"packageManager": "[email protected]", | ||
"engines": { | ||
"node": ">=18.0.0" | ||
}, | ||
"scripts": { | ||
"build": "nest build -p ./tsconfig.json", | ||
"dev": "nest start --watch", | ||
"lint": "eslint .", | ||
"lint:fix": "eslint . --fix" | ||
}, | ||
"devDependencies": { | ||
"@nestjs/cli": "9.4.2", | ||
"@tsconfig/esm": "1.0.3", | ||
"@tsconfig/node18": "2.0.0", | ||
"@tsconfig/strictest": "2.0.1", | ||
"@types/express": "4.17.17", | ||
"@types/morgan": "1.9.4", | ||
"@types/node": "18.16.3", | ||
"@typescript-eslint/eslint-plugin": "5.59.1", | ||
"@typescript-eslint/parser": "5.59.1", | ||
"eslint": "8.39.0", | ||
"eslint-config-airbnb-base": "15.0.0", | ||
"eslint-config-airbnb-typescript": "17.0.0", | ||
"eslint-config-prettier": "8.8.0", | ||
"eslint-plugin-import": "2.27.5", | ||
"eslint-plugin-n": "15.7.0", | ||
"eslint-plugin-prettier": "4.2.1", | ||
"prettier": "2.8.8" | ||
}, | ||
"dependencies": { | ||
"@nestjs/common": "9.4.0", | ||
"@nestjs/config": "2.3.1", | ||
"@nestjs/core": "9.4.0", | ||
"@nestjs/platform-express": "9.4.0", | ||
"express": "4.18.2", | ||
"morgan": "1.10.0", | ||
"node-fetch": "^3.3.1", | ||
"reflect-metadata": "0.1.13", | ||
"typescript": "5.0.4", | ||
"zod": "3.21.4" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { Module } from '@nestjs/common'; | ||
import { ConfigModule, ConfigService } from '@nestjs/config'; | ||
import { z } from 'zod'; | ||
import { HydraController } from './hydra.controller.js'; | ||
|
||
const envSchema = z.object({ | ||
TARGET_HOST: z.string(), | ||
USER_FIELD: z.string().optional(), | ||
}); | ||
|
||
export type EnvironmentVariables = z.infer<typeof envSchema>; | ||
|
||
export type AppConfigService = ConfigService<EnvironmentVariables>; | ||
|
||
@Module({ | ||
controllers: [HydraController], | ||
exports: [], | ||
imports: [ | ||
ConfigModule.forRoot({ | ||
cache: true, | ||
isGlobal: true, | ||
validate: config => envSchema.parse(config), | ||
}), | ||
], | ||
providers: [], | ||
}) | ||
export class AppModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { | ||
BadRequestException, | ||
Controller, | ||
Inject, | ||
Logger, | ||
Req, | ||
RequestMapping, | ||
RequestMethod, | ||
Res, | ||
} from '@nestjs/common'; | ||
import { ConfigService } from '@nestjs/config'; | ||
import type { Request, Response } from 'express'; | ||
import fetch, { type RequestInit } from 'node-fetch'; | ||
import type { AppConfigService } from './app.module.js'; | ||
|
||
@Controller({ path: '*' }) | ||
export class HydraController { | ||
private readonly logger = new Logger(HydraController.name); | ||
|
||
constructor( | ||
@Inject(ConfigService) | ||
private configService: AppConfigService, | ||
) {} | ||
|
||
@RequestMapping({ path: '*', method: RequestMethod.ALL }) | ||
async index(@Req() req: Request, @Res() clientResponse: Response): Promise<void> { | ||
const { method, url, headers } = req; | ||
|
||
const [type, base64] = headers.authorization?.split(' ') ?? []; | ||
|
||
if (!type || !base64) { | ||
throw new BadRequestException(`Missing authorization header`); | ||
} | ||
|
||
if (type !== 'Basic') { | ||
throw new BadRequestException(`Unsupported authorization type: ${type}`); | ||
} | ||
|
||
const [user, password] = Buffer.from(base64, 'base64').toString().split(':'); | ||
|
||
if (!user || !password) { | ||
throw new BadRequestException(`Missing user or password`); | ||
} | ||
|
||
const userField = this.configService.get('USER_FIELD', { infer: true }) ?? 'username'; | ||
|
||
const body = JSON.stringify({ [userField]: user, password }); | ||
|
||
const targetUrl = new URL(url, `https://${this.configService.getOrThrow('TARGET_HOST', { infer: true })}`); | ||
|
||
const reqInit: RequestInit = { | ||
method, | ||
body, | ||
headers: { 'content-type': 'application/json' }, | ||
}; | ||
|
||
try { | ||
const targetResponse = await fetch(targetUrl, reqInit); | ||
|
||
if (targetResponse.status >= 500) { | ||
this.logger.warn(`Target server responded with ${targetResponse.status}`); | ||
} | ||
|
||
targetResponse.headers.forEach((value, key) => { | ||
clientResponse.setHeader(key, value); | ||
}); | ||
|
||
clientResponse.status(targetResponse.status).send(targetResponse.body); | ||
} catch (err) { | ||
this.logger.error(err); | ||
this.logger.log(reqInit); | ||
throw err; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { NestFactory } from '@nestjs/core'; | ||
import morgan from 'morgan'; | ||
import { Logger } from '@nestjs/common'; | ||
import { AppModule } from './app.module.js'; | ||
|
||
async function bootstrap() { | ||
const app = await NestFactory.create(AppModule); | ||
const morganLogger = new Logger('morgan'); | ||
app.use( | ||
morgan('[:date[iso]] ":method :url HTTP/:http-version" :status :res[content-length]', { | ||
stream: { | ||
write: msg => morganLogger.debug(msg.trim()), | ||
}, | ||
}), | ||
); | ||
await app.listen(80); | ||
} | ||
|
||
bootstrap().catch(err => | ||
// eslint-disable-next-line no-console -- we're in main | ||
console.error(err), | ||
); |
Oops, something went wrong.