mirror of
https://github.com/pockethost/pockethost.git
synced 2025-03-30 15:08:30 +00:00
refactor ftp
This commit is contained in:
parent
f51fc0f413
commit
b09014d0a1
@ -13,4 +13,7 @@ DAEMON_PB_BACKUP_SLEEP=100
|
||||
DAEMON_PB_BACKUP_PAGE_COUNT=5
|
||||
SSL_KEY=`pwd`/ssl/pockethost.test.key
|
||||
SSL_CERT=`pwd`/ssl/pockethost.test.crt
|
||||
PH_BIN_CACHE=`pwd`/.pbincache
|
||||
PH_BIN_CACHE=`pwd`/.pbincache
|
||||
PH_FTP_PASV_IP=0.0.0.0
|
||||
PH_FTP_PASV_PORT_MIN=10000
|
||||
PH_FTP_PASV_PORT_MAX=20000
|
@ -56,3 +56,7 @@ export const PH_FTP_PORT = envi('PH_FTP_PORT', 21)
|
||||
|
||||
export const SSL_KEY = env('SSL_KEY')
|
||||
export const SSL_CERT = env('SSL_CERT')
|
||||
|
||||
export const PH_FTP_PASV_IP = env('PH_FTP_PASV_IP', '0.0.0.0')
|
||||
export const PH_FTP_PASV_PORT_MIN = envi('PH_FTP_PASV_PORT_MIN', 10000)
|
||||
export const PH_FTP_PASV_PORT_MAX = envi('PH_FTP_PASV_PORT_MAX', 20000)
|
||||
|
@ -2,7 +2,7 @@ import { logger } from '@pockethost/common'
|
||||
import { DEBUG, PH_BIN_CACHE, PUBLIC_PB_SUBDOMAIN } from './constants'
|
||||
import { clientService } from './db/PbClient'
|
||||
import { createBackupService } from './services/BackupService'
|
||||
import { ftpService } from './services/FtpService'
|
||||
import { ftpService } from './services/FtpService/FtpService'
|
||||
import { createInstanceService } from './services/InstanceService'
|
||||
import { pocketbase } from './services/PocketBaseService'
|
||||
import { createProxyService } from './services/ProxyService'
|
||||
|
90
packages/daemon/src/services/FtpService/FtpService.ts
Normal file
90
packages/daemon/src/services/FtpService/FtpService.ts
Normal file
@ -0,0 +1,90 @@
|
||||
import { logger, mkSingleton } from '@pockethost/common'
|
||||
import { readFileSync } from 'fs'
|
||||
import { FtpSrv } from 'ftp-srv'
|
||||
import {
|
||||
PH_FTP_PASV_IP,
|
||||
PH_FTP_PASV_PORT_MAX,
|
||||
PH_FTP_PASV_PORT_MIN,
|
||||
PH_FTP_PORT,
|
||||
SSL_CERT,
|
||||
SSL_KEY,
|
||||
} from '../../constants'
|
||||
import { clientService, createPbClient } from '../../db/PbClient'
|
||||
import { PhFs } from './PhFs'
|
||||
|
||||
export type FtpConfig = {}
|
||||
|
||||
export enum FolderNames {
|
||||
PbData = 'pb_data',
|
||||
PbStatic = 'pb_static',
|
||||
PbWorkers = 'workers',
|
||||
PbBackup = 'backup',
|
||||
}
|
||||
|
||||
export const README_CONTENTS: { [_ in FolderNames]: string } = {
|
||||
[FolderNames.PbBackup]: `This directory contains tgz backups of your data. PocketHost creates these automatically, or you can create them manually. For more information, see https://pockethost.io/docs/backups`,
|
||||
[FolderNames.PbData]: `This directory contains your PocketBase data. For more information, see https://pockethost.io/docs/data`,
|
||||
[FolderNames.PbStatic]: `This directory contains static files such as your web frontend. PocketHost will serve these when your instance URL receives a request. For more information, see https://pockethost.io/docs/static `,
|
||||
[FolderNames.PbWorkers]: `This directory contains your Deno workers. For more information, see https://pockethost.io/docs/workers`,
|
||||
}
|
||||
export const README_NAME = 'readme.md'
|
||||
|
||||
export const FOLDER_NAMES: FolderNames[] = [
|
||||
FolderNames.PbBackup,
|
||||
FolderNames.PbData,
|
||||
FolderNames.PbStatic,
|
||||
FolderNames.PbWorkers,
|
||||
]
|
||||
|
||||
export function isFolder(name: string): name is FolderNames {
|
||||
return FOLDER_NAMES.includes(name as FolderNames)
|
||||
}
|
||||
|
||||
const tls = {
|
||||
key: readFileSync(SSL_KEY || ''),
|
||||
cert: readFileSync(SSL_CERT || ''),
|
||||
}
|
||||
|
||||
export const ftpService = mkSingleton((config: FtpConfig) => {
|
||||
const log = logger().create('FtpService')
|
||||
const { dbg, info } = log
|
||||
|
||||
const ftpServer = new FtpSrv({
|
||||
url: 'ftp://0.0.0.0:' + PH_FTP_PORT,
|
||||
anonymous: false,
|
||||
log: log.create(`ftpServer`, { errorTrace: false }),
|
||||
tls,
|
||||
pasv_url: PH_FTP_PASV_IP,
|
||||
pasv_max: PH_FTP_PASV_PORT_MAX,
|
||||
pasv_min: PH_FTP_PASV_PORT_MIN,
|
||||
})
|
||||
|
||||
ftpServer.on(
|
||||
'login',
|
||||
async ({ connection, username, password }, resolve, reject) => {
|
||||
const url = (await clientService()).url
|
||||
const client = createPbClient(url)
|
||||
try {
|
||||
await client.client
|
||||
.collection('users')
|
||||
.authWithPassword(username, password)
|
||||
dbg(`Logged in`)
|
||||
const fs = new PhFs(connection, client)
|
||||
resolve({ fs })
|
||||
} catch (e) {
|
||||
reject(new Error(`Invalid username or password`))
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
ftpServer.listen().then(() => {
|
||||
info('Ftp server is starting...')
|
||||
})
|
||||
|
||||
const shutdown = () => {
|
||||
info(`Closing FTP server`)
|
||||
ftpServer.close()
|
||||
}
|
||||
|
||||
return { shutdown }
|
||||
})
|
@ -1,49 +1,18 @@
|
||||
import { Logger, logger, mkSingleton } from '@pockethost/common'
|
||||
import { existsSync, mkdirSync, readFileSync } from 'fs'
|
||||
import { FileStat, FileSystem, FtpConnection, FtpSrv } from 'ftp-srv'
|
||||
import { Logger, logger } from '@pockethost/common'
|
||||
import { existsSync, mkdirSync } from 'fs'
|
||||
import { FileStat, FileSystem, FtpConnection } from 'ftp-srv'
|
||||
import { join } from 'path'
|
||||
import { Readable } from 'stream'
|
||||
import { DAEMON_PB_DATA_DIR } from '../../constants'
|
||||
import { PocketbaseClientApi } from '../../db/PbClient'
|
||||
import {
|
||||
DAEMON_PB_DATA_DIR,
|
||||
PH_FTP_PORT,
|
||||
SSL_CERT,
|
||||
SSL_KEY,
|
||||
} from '../constants'
|
||||
import {
|
||||
clientService,
|
||||
createPbClient,
|
||||
PocketbaseClientApi,
|
||||
} from '../db/PbClient'
|
||||
FOLDER_NAMES,
|
||||
isFolder,
|
||||
README_CONTENTS,
|
||||
README_NAME,
|
||||
} from './FtpService'
|
||||
|
||||
export type FtpConfig = {}
|
||||
|
||||
export enum FolderNames {
|
||||
PbData = 'pb_data',
|
||||
PbStatic = 'pb_static',
|
||||
PbWorkers = 'workers',
|
||||
PbBackup = 'backup',
|
||||
}
|
||||
|
||||
const README_CONTENTS: { [_ in FolderNames]: string } = {
|
||||
[FolderNames.PbBackup]: `This directory contains tgz backups of your data. PocketHost creates these automatically, or you can create them manually. For more information, see https://pockethost.io/docs/backups`,
|
||||
[FolderNames.PbData]: `This directory contains your PocketBase data. For more information, see https://pockethost.io/docs/data`,
|
||||
[FolderNames.PbStatic]: `This directory contains static files such as your web frontend. PocketHost will serve these when your instance URL receives a request. For more information, see https://pockethost.io/docs/static `,
|
||||
[FolderNames.PbWorkers]: `This directory contains your Deno workers. For more information, see https://pockethost.io/docs/workers`,
|
||||
}
|
||||
const README_NAME = 'readme.md'
|
||||
|
||||
const FOLDER_NAMES: FolderNames[] = [
|
||||
FolderNames.PbBackup,
|
||||
FolderNames.PbData,
|
||||
FolderNames.PbStatic,
|
||||
FolderNames.PbWorkers,
|
||||
]
|
||||
|
||||
function isFolder(name: string): name is FolderNames {
|
||||
return FOLDER_NAMES.includes(name as FolderNames)
|
||||
}
|
||||
|
||||
class PhFs extends FileSystem {
|
||||
export class PhFs extends FileSystem {
|
||||
private log: Logger
|
||||
private client: PocketbaseClientApi
|
||||
|
||||
@ -264,52 +233,3 @@ class PhFs extends FileSystem {
|
||||
throw new Error(`getUniqueName ${fileName}`)
|
||||
}
|
||||
}
|
||||
|
||||
const tls = {
|
||||
key: readFileSync(SSL_KEY || ''),
|
||||
cert: readFileSync(SSL_CERT || ''),
|
||||
}
|
||||
|
||||
export const ftpService = mkSingleton((config: FtpConfig) => {
|
||||
const log = logger().create('FtpService')
|
||||
const { dbg, info } = log
|
||||
|
||||
const ftpServer = new FtpSrv({
|
||||
url: 'ftp://0.0.0.0:' + PH_FTP_PORT,
|
||||
anonymous: false,
|
||||
log: log.create(`ftpServer`, { errorTrace: false }),
|
||||
tls,
|
||||
pasv_url: `147.182.196.168`,
|
||||
pasv_max: 20000,
|
||||
pasv_min: 10000,
|
||||
})
|
||||
|
||||
ftpServer.on(
|
||||
'login',
|
||||
async ({ connection, username, password }, resolve, reject) => {
|
||||
const url = (await clientService()).url
|
||||
const client = createPbClient(url)
|
||||
try {
|
||||
await client.client
|
||||
.collection('users')
|
||||
.authWithPassword(username, password)
|
||||
dbg(`Logged in`)
|
||||
const fs = new PhFs(connection, client)
|
||||
resolve({ fs })
|
||||
} catch (e) {
|
||||
reject(new Error(`Invalid username or password`))
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
ftpServer.listen().then(() => {
|
||||
info('Ftp server is starting...')
|
||||
})
|
||||
|
||||
const shutdown = () => {
|
||||
info(`Closing FTP server`)
|
||||
ftpServer.close()
|
||||
}
|
||||
|
||||
return { shutdown }
|
||||
})
|
Loading…
x
Reference in New Issue
Block a user