mirror of
https://gitlab.com/MrFry/mrfrys-node-server
synced 2025-04-01 20:24:18 +02:00
p2p https and login fix, removed static domain from ejs files
This commit is contained in:
parent
ae3bd7c55a
commit
e858d7f23e
13 changed files with 210 additions and 79 deletions
|
@ -69,6 +69,8 @@ To setup P2P functionality you have to create a few files in `./data/p2p`:
|
||||||
* `peers.json` : an array, with objects same as above, and `{ publicKey: "public key of the server"
|
* `peers.json` : an array, with objects same as above, and `{ publicKey: "public key of the server"
|
||||||
}`. Public key is used to encrypt the users database in the response, so they can be synced too.
|
}`. Public key is used to encrypt the users database in the response, so they can be synced too.
|
||||||
|
|
||||||
|
Extra configuration: HTTP and pw! TODO
|
||||||
|
|
||||||
Uppon syncing data or having a peer request data from your server there will be new entries in
|
Uppon syncing data or having a peer request data from your server there will be new entries in
|
||||||
`./data/p2p/thirdPartyPeers.json`. Here you can review the peers, see their contact and host, and if
|
`./data/p2p/thirdPartyPeers.json`. Here you can review the peers, see their contact and host, and if
|
||||||
you choose you can add them to your `peers.json` file. `thirdPartyPeers.json` should also contain
|
you choose you can add them to your `peers.json` file. `thirdPartyPeers.json` should also contain
|
||||||
|
@ -138,7 +140,6 @@ needed at all
|
||||||
| NS_THREAD_COUNT | number | Nubmer of CPU cores to use |
|
| NS_THREAD_COUNT | number | Nubmer of CPU cores to use |
|
||||||
| NS_NOUSER | boolean | If the authorization should be skipped (for testing) |
|
| NS_NOUSER | boolean | If the authorization should be skipped (for testing) |
|
||||||
| NS_NO_HTTPS_FORCE | boolean | Disables automatic redirects from http to https |
|
| NS_NO_HTTPS_FORCE | boolean | Disables automatic redirects from http to https |
|
||||||
| NS_DEVEL | boolean | Developemnt mode. Now it only forces login page to use localhost |
|
|
||||||
| NS_LOGLEVEL | number | Debug log level, 0 is the least verbose |
|
| NS_LOGLEVEL | number | Debug log level, 0 is the least verbose |
|
||||||
| NS_NOLOG | boolean | If logging should be skipped |
|
| NS_NOLOG | boolean | If logging should be skipped |
|
||||||
| NS_SQL_DEBUG_LOG | boolean | If the SQL queries should be logged |
|
| NS_SQL_DEBUG_LOG | boolean | If the SQL queries should be logged |
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node ./dist/server.js",
|
"start": "node ./dist/server.js",
|
||||||
"dev": "npm run build && NS_THREAD_COUNT=2 NS_DEVEL=1 NS_NOUSER=1 node --inspect ./dist/server.js",
|
"dev": "npm run build && NS_NO_HTTPS_FORCE=1 NS_THREAD_COUNT=2 NS_NOUSER=1 node --inspect ./dist/server.js",
|
||||||
"build": "tsc && bash -c './scripts/postBuild.sh'",
|
"build": "tsc && bash -c './scripts/postBuild.sh'",
|
||||||
"export": "tsc && bash -c './scripts/postBuild.sh'",
|
"export": "tsc && bash -c './scripts/postBuild.sh'",
|
||||||
"test": "NS_NOLOG=1 NS_THREAD_COUNT=1 jest",
|
"test": "NS_NOLOG=1 NS_THREAD_COUNT=1 jest",
|
||||||
|
|
|
@ -24,6 +24,10 @@ import type { Database } from 'better-sqlite3'
|
||||||
|
|
||||||
import logger from '../utils/logger'
|
import logger from '../utils/logger'
|
||||||
import dbtools from '../utils/dbtools'
|
import dbtools from '../utils/dbtools'
|
||||||
|
import { paths } from '../utils/files'
|
||||||
|
import utils from '../utils/utils'
|
||||||
|
|
||||||
|
const domain = utils.ReadFile(paths.domainFile).trim()
|
||||||
|
|
||||||
interface Options {
|
interface Options {
|
||||||
userDB: Database
|
userDB: Database
|
||||||
|
@ -31,7 +35,7 @@ interface Options {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const testUser: User = {
|
export const testUser: User = {
|
||||||
id: 19,
|
id: 1,
|
||||||
avaiblePWRequests: 645,
|
avaiblePWRequests: 645,
|
||||||
pwRequestCount: 19,
|
pwRequestCount: 19,
|
||||||
created: new Date().getTime(),
|
created: new Date().getTime(),
|
||||||
|
@ -51,7 +55,8 @@ function renderLogin(req: Request, res: Response) {
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
res.render('login', {
|
res.render('login', {
|
||||||
devel: process.env.NS_DEVEL,
|
useHttp: process.env.NS_NO_HTTPS_FORCE,
|
||||||
|
domain: domain,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,7 @@ function GetApp(): ModuleType {
|
||||||
|
|
||||||
function reloadRootRedirectURL() {
|
function reloadRootRedirectURL() {
|
||||||
if (utils.FileExists(paths.rootRedirectToFile)) {
|
if (utils.FileExists(paths.rootRedirectToFile)) {
|
||||||
rootRedirectURL = utils.ReadFile(paths.rootRedirectToFile)
|
rootRedirectURL = utils.ReadFile(paths.rootRedirectToFile).trim()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
import { Response } from 'express'
|
import { Response } from 'express'
|
||||||
import http from 'http'
|
|
||||||
|
|
||||||
import logger from '../../../utils/logger'
|
import logger from '../../../utils/logger'
|
||||||
import {
|
import {
|
||||||
|
@ -60,6 +59,7 @@ import {
|
||||||
SelfInfoSchema,
|
SelfInfoSchema,
|
||||||
} from '../../../types/typeSchemas'
|
} from '../../../types/typeSchemas'
|
||||||
import { paths } from '../../../utils/files'
|
import { paths } from '../../../utils/files'
|
||||||
|
import { GetResult, get, post } from '../../../utils/networkUtils'
|
||||||
|
|
||||||
interface MergeResult {
|
interface MergeResult {
|
||||||
newData: Subject[]
|
newData: Subject[]
|
||||||
|
@ -87,47 +87,17 @@ interface RemotePeerInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RequestResult<T> {
|
|
||||||
data?: T
|
|
||||||
error?: Error
|
|
||||||
options?: http.RequestOptions
|
|
||||||
}
|
|
||||||
|
|
||||||
interface SyncDataRes {
|
interface SyncDataRes {
|
||||||
questionDbs?: QuestionDb[]
|
questionDbs?: QuestionDb[]
|
||||||
remoteInfo?: RemotePeerInfo
|
remoteInfo?: RemotePeerInfo
|
||||||
encryptedUsers?: string
|
encryptedUsers?: string
|
||||||
count: {
|
count?: {
|
||||||
qdbs: number
|
qdbs: number
|
||||||
subjects: number
|
subjects: number
|
||||||
questions: number
|
questions: number
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: to utils/http.ts
|
|
||||||
function get<T>(options: http.RequestOptions): Promise<RequestResult<T>> {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
const req = http.get(options, function (res) {
|
|
||||||
const bodyChunks: Uint8Array[] = []
|
|
||||||
res.on('data', (chunk) => {
|
|
||||||
bodyChunks.push(chunk)
|
|
||||||
}).on('end', () => {
|
|
||||||
const body = Buffer.concat(bodyChunks).toString()
|
|
||||||
try {
|
|
||||||
resolve({ data: JSON.parse(body) })
|
|
||||||
} catch (e) {
|
|
||||||
console.log(body)
|
|
||||||
resolve({ error: e, options: options })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
req.on('error', function (e) {
|
|
||||||
resolve({ error: e, options: options })
|
|
||||||
// reject(e)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateThirdPartyPeers(
|
function updateThirdPartyPeers(
|
||||||
newVal: Omit<PeerInfo, 'publicKey' | 'name' | 'contact'>[]
|
newVal: Omit<PeerInfo, 'publicKey' | 'name' | 'contact'>[]
|
||||||
) {
|
) {
|
||||||
|
@ -341,6 +311,54 @@ function setupQuestionsForMerge(qdb: QuestionDb, peer: PeerInfo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function authAndGetNewData({
|
||||||
|
peer,
|
||||||
|
selfInfo,
|
||||||
|
lastSyncWithPeer,
|
||||||
|
lastSync,
|
||||||
|
}: {
|
||||||
|
peer: PeerInfo
|
||||||
|
selfInfo: PeerInfo
|
||||||
|
lastSyncWithPeer: number
|
||||||
|
lastSync: number
|
||||||
|
}): Promise<GetResult<SyncDataRes & { peer: PeerInfo }>> {
|
||||||
|
const { data, error, cookies } = await post<{
|
||||||
|
result: string
|
||||||
|
msg: string
|
||||||
|
}>({
|
||||||
|
hostname: peer.host,
|
||||||
|
path: '/api/login',
|
||||||
|
port: peer.port,
|
||||||
|
bodyObject: { pw: peer.pw },
|
||||||
|
http: peer.http,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (error || !data || data.result !== 'success') {
|
||||||
|
return {
|
||||||
|
error: data ? new Error(data.msg) : error,
|
||||||
|
data: {
|
||||||
|
peer: peer,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getRes = await get<SyncDataRes>(
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
cookie: cookies.join(),
|
||||||
|
},
|
||||||
|
host: peer.host,
|
||||||
|
port: peer.port,
|
||||||
|
path: `/api/getnewdatasince?host=${encodeURIComponent(
|
||||||
|
peerToString(selfInfo)
|
||||||
|
)}${lastSync ? `&since=${lastSyncWithPeer}` : ''}`,
|
||||||
|
},
|
||||||
|
peer.http
|
||||||
|
)
|
||||||
|
|
||||||
|
return { ...getRes, data: { ...getRes.data, peer: peer } }
|
||||||
|
}
|
||||||
|
|
||||||
function setup(data: SubmoduleData): Submodule {
|
function setup(data: SubmoduleData): Submodule {
|
||||||
const {
|
const {
|
||||||
app,
|
app,
|
||||||
|
@ -453,16 +471,20 @@ function setup(data: SubmoduleData): Submodule {
|
||||||
// FUNCTIONS
|
// FUNCTIONS
|
||||||
// ---------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------
|
||||||
|
|
||||||
function getSelfInfo(includeQdbInfo?: boolean) {
|
function getSelfInfo(includeVerboseInfo?: boolean) {
|
||||||
const result: RemotePeerInfo = {
|
const result: RemotePeerInfo = {
|
||||||
selfInfo: selfInfo,
|
selfInfo: selfInfo,
|
||||||
myPeers: peers,
|
myPeers: peers,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (includeVerboseInfo) {
|
||||||
result.serverRevision = utils.getGitRevision(__dirname)
|
result.serverRevision = utils.getGitRevision(__dirname)
|
||||||
result.scriptRevision = utils.getGitRevision(
|
result.scriptRevision = utils.getGitRevision(
|
||||||
paths.moodleTestUserscriptDir
|
paths.moodleTestUserscriptDir
|
||||||
)
|
)
|
||||||
result.qminingPageRevision = utils.getGitRevision(paths.qminingPageDir)
|
result.qminingPageRevision = utils.getGitRevision(
|
||||||
|
paths.qminingPageDir
|
||||||
|
)
|
||||||
result.dataEditorRevision = utils.getGitRevision(
|
result.dataEditorRevision = utils.getGitRevision(
|
||||||
paths.dataEditorPageDir
|
paths.dataEditorPageDir
|
||||||
)
|
)
|
||||||
|
@ -478,7 +500,6 @@ function setup(data: SubmoduleData): Submodule {
|
||||||
result.scriptVersion = utils.getScriptVersion()
|
result.scriptVersion = utils.getScriptVersion()
|
||||||
result.userCount = dbtools.TableInfo(userDB, 'users').dataCount
|
result.userCount = dbtools.TableInfo(userDB, 'users').dataCount
|
||||||
|
|
||||||
if (includeQdbInfo) {
|
|
||||||
const questionDbCount = getQuestionDbs().length
|
const questionDbCount = getQuestionDbs().length
|
||||||
const { subjCount, questionCount } = countOfQdbs(getQuestionDbs())
|
const { subjCount, questionCount } = countOfQdbs(getQuestionDbs())
|
||||||
result.qdbInfo = {
|
result.qdbInfo = {
|
||||||
|
@ -585,19 +606,12 @@ function setup(data: SubmoduleData): Submodule {
|
||||||
const requests = peers.map((peer) => {
|
const requests = peers.map((peer) => {
|
||||||
const lastSyncWithPeer = peer.lastSync || 0
|
const lastSyncWithPeer = peer.lastSync || 0
|
||||||
|
|
||||||
return new Promise<RequestResult<SyncDataRes & { peer: PeerInfo }>>(
|
return authAndGetNewData({
|
||||||
(resolve) => {
|
peer: peer,
|
||||||
get<SyncDataRes>({
|
selfInfo: selfInfo,
|
||||||
host: peer.host,
|
lastSyncWithPeer: lastSyncWithPeer,
|
||||||
port: peer.port,
|
lastSync: lastSync,
|
||||||
path: `/getnewdatasince?host=${encodeURIComponent(
|
|
||||||
peerToString(selfInfo)
|
|
||||||
)}${lastSync ? `&since=${lastSyncWithPeer}` : ''}`,
|
|
||||||
}).then((res) => {
|
|
||||||
resolve({ ...res, data: { ...res.data, peer: peer } })
|
|
||||||
})
|
})
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const allResults = await Promise.all(requests)
|
const allResults = await Promise.all(requests)
|
||||||
|
@ -912,6 +926,10 @@ function setup(data: SubmoduleData): Submodule {
|
||||||
// ---------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------
|
||||||
// APP SETUP
|
// APP SETUP
|
||||||
// ---------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------
|
||||||
|
app.get('/selfInfo', (_req: Request, res: Response<PeerInfo>) => {
|
||||||
|
res.json(selfInfo)
|
||||||
|
})
|
||||||
|
|
||||||
app.get('/p2pinfo', (_req: Request, res: Response<RemotePeerInfo>) => {
|
app.get('/p2pinfo', (_req: Request, res: Response<RemotePeerInfo>) => {
|
||||||
res.json(getSelfInfo(true))
|
res.json(getSelfInfo(true))
|
||||||
})
|
})
|
||||||
|
|
|
@ -68,7 +68,7 @@ function createDefaultUser(userDb: Database) {
|
||||||
const pw = uuidv4()
|
const pw = uuidv4()
|
||||||
const insertRes = dbtools.Insert(userDb, 'users', {
|
const insertRes = dbtools.Insert(userDb, 'users', {
|
||||||
pw: pw,
|
pw: pw,
|
||||||
avaiblePWRequests: 0,
|
avaiblePWRequests: 50,
|
||||||
created: utils.GetDateString(),
|
created: utils.GetDateString(),
|
||||||
})
|
})
|
||||||
logger.Log('ID and PW for user #1: ', 'yellowbg')
|
logger.Log('ID and PW for user #1: ', 'yellowbg')
|
||||||
|
|
|
@ -267,7 +267,7 @@ app.get('*', (req, res) => {
|
||||||
if (req.is('application/json')) {
|
if (req.is('application/json')) {
|
||||||
res.status(404).end()
|
res.status(404).end()
|
||||||
} else {
|
} else {
|
||||||
res.status(404).render('404')
|
res.status(404).render('404', { domain: domain })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<body bgcolor="#222426">
|
<body bgcolor="#222426">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>Nem található - Qmining | Frylabs.net</title>
|
<title>Qmining | <%= domain %> - 404</title>
|
||||||
<style>
|
<style>
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Kameron&family=Overpass+Mono:wght@300;400&display=swap');
|
@import url('https://fonts.googleapis.com/css2?family=Kameron&family=Overpass+Mono:wght@300;400&display=swap');
|
||||||
body {
|
body {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<html>
|
<html>
|
||||||
<body bgcolor="#222426">
|
<body bgcolor="#222426">
|
||||||
<head>
|
<head>
|
||||||
<title>Qmining | Frylabs.net - Login</title>
|
<title>Qmining | <%= domain %> - Login</title>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=0.6" />
|
<meta name="viewport" content="width=device-width, initial-scale=0.6" />
|
||||||
<style>
|
<style>
|
||||||
|
@ -123,7 +123,7 @@
|
||||||
button.classList.add('disabledButton')
|
button.classList.add('disabledButton')
|
||||||
button.disabled = true
|
button.disabled = true
|
||||||
// TODO: get url from controller
|
// TODO: get url from controller
|
||||||
const rawResponse = await fetch('<%= devel ? 'http://localhost:8080/api/login' : 'https://frylabs.net/api/login' %>', {
|
const rawResponse = await fetch('<%= useHttp ? `http://${domain}/api/login` : `https://${domain}/api/login` %>', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
credentials: 'include',
|
credentials: 'include',
|
||||||
headers: {
|
headers: {
|
||||||
|
|
|
@ -98,6 +98,7 @@ export interface User {
|
||||||
lastLogin: number
|
lastLogin: number
|
||||||
lastAccess: number
|
lastAccess: number
|
||||||
sourceHost?: number
|
sourceHost?: number
|
||||||
|
// isAdmin: boolean // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Request<T = any> extends express.Request {
|
export interface Request<T = any> extends express.Request {
|
||||||
|
@ -174,6 +175,8 @@ export interface PeerInfo {
|
||||||
port: number
|
port: number
|
||||||
publicKey: string
|
publicKey: string
|
||||||
contact: string
|
contact: string
|
||||||
|
pw?: string
|
||||||
lastSync?: number
|
lastSync?: number
|
||||||
note?: string
|
note?: string
|
||||||
|
http?: boolean
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,8 +46,10 @@ const PeerInfoSchemaBase = {
|
||||||
contact: { type: 'string' },
|
contact: { type: 'string' },
|
||||||
lastSync: { type: 'number' },
|
lastSync: { type: 'number' },
|
||||||
note: { type: 'string' },
|
note: { type: 'string' },
|
||||||
|
pw: { type: 'string' },
|
||||||
|
http: { type: 'boolean' },
|
||||||
},
|
},
|
||||||
required: ['name', 'host', 'port'],
|
required: ['name', 'host', 'port', 'contact', 'pw'],
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SelfInfoSchema: Schema = {
|
export const SelfInfoSchema: Schema = {
|
||||||
|
|
|
@ -3,8 +3,8 @@ import {
|
||||||
TestUsersSchema,
|
TestUsersSchema,
|
||||||
isJsonValidAndLogError,
|
isJsonValidAndLogError,
|
||||||
PeersInfoSchema,
|
PeersInfoSchema,
|
||||||
PeerInfoSchema,
|
|
||||||
ModulesSchema,
|
ModulesSchema,
|
||||||
|
SelfInfoSchema,
|
||||||
} from '../types/typeSchemas'
|
} from '../types/typeSchemas'
|
||||||
import logger from './logger'
|
import logger from './logger'
|
||||||
import utils from './utils'
|
import utils from './utils'
|
||||||
|
@ -230,7 +230,7 @@ export const files = {
|
||||||
path: 'data/p2p/selfInfo.json',
|
path: 'data/p2p/selfInfo.json',
|
||||||
description: 'json of info of this servers peer functionality',
|
description: 'json of info of this servers peer functionality',
|
||||||
defaultValue: JSON.stringify({}),
|
defaultValue: JSON.stringify({}),
|
||||||
schema: PeerInfoSchema,
|
schema: SelfInfoSchema,
|
||||||
},
|
},
|
||||||
thirdPartyPeersFile: {
|
thirdPartyPeersFile: {
|
||||||
path: 'data/p2p/thirdPartyPeers.json',
|
path: 'data/p2p/thirdPartyPeers.json',
|
||||||
|
|
102
src/utils/networkUtils.ts
Normal file
102
src/utils/networkUtils.ts
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
import http, { request as httpRequest } from 'http'
|
||||||
|
import https, { request as httpsRequest } from 'https'
|
||||||
|
|
||||||
|
export interface GetResult<T> {
|
||||||
|
data?: T
|
||||||
|
error?: Error
|
||||||
|
options?: http.RequestOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
export function get<T = any>(
|
||||||
|
options: http.RequestOptions,
|
||||||
|
useHttp?: boolean
|
||||||
|
): Promise<GetResult<T>> {
|
||||||
|
const provider = useHttp ? http : https
|
||||||
|
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const req = provider.get(options, function (res) {
|
||||||
|
const bodyChunks: Uint8Array[] = []
|
||||||
|
res.on('data', (chunk) => {
|
||||||
|
bodyChunks.push(chunk)
|
||||||
|
}).on('end', () => {
|
||||||
|
const body = Buffer.concat(bodyChunks).toString()
|
||||||
|
try {
|
||||||
|
resolve({ data: JSON.parse(body) })
|
||||||
|
} catch (e) {
|
||||||
|
console.log(body)
|
||||||
|
resolve({ error: e, options: options })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
req.on('error', function (e) {
|
||||||
|
resolve({ error: e, options: options })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PostResult<T> {
|
||||||
|
data?: T
|
||||||
|
error?: Error
|
||||||
|
cookies?: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PostParams {
|
||||||
|
hostname: string
|
||||||
|
path: string
|
||||||
|
port: number
|
||||||
|
bodyObject: any
|
||||||
|
http?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://nodejs.org/api/http.html#httprequesturl-options-callback
|
||||||
|
export function post<T = any>({
|
||||||
|
hostname,
|
||||||
|
path,
|
||||||
|
port,
|
||||||
|
bodyObject,
|
||||||
|
http,
|
||||||
|
}: PostParams): Promise<PostResult<T>> {
|
||||||
|
const provider = http ? httpRequest : httpsRequest
|
||||||
|
const body = JSON.stringify(bodyObject)
|
||||||
|
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const req = provider(
|
||||||
|
{
|
||||||
|
hostname: hostname,
|
||||||
|
port: port,
|
||||||
|
path: path,
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Content-Length': Buffer.byteLength(body),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
(res) => {
|
||||||
|
const bodyChunks: string[] = []
|
||||||
|
res.setEncoding('utf8')
|
||||||
|
res.on('data', (chunk) => {
|
||||||
|
bodyChunks.push(chunk)
|
||||||
|
})
|
||||||
|
res.on('end', () => {
|
||||||
|
const body = bodyChunks.join()
|
||||||
|
try {
|
||||||
|
resolve({
|
||||||
|
data: JSON.parse(body),
|
||||||
|
cookies: res.headers['set-cookie'],
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
console.log(body)
|
||||||
|
resolve({ error: e })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
req.on('error', (e) => {
|
||||||
|
resolve({ error: e })
|
||||||
|
})
|
||||||
|
|
||||||
|
req.write(body)
|
||||||
|
req.end()
|
||||||
|
})
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue