chore(root): update ftp server - not ready yet

This commit is contained in:
Ben Allfree 2024-06-28 14:23:38 -07:00
parent 6e14f576e4
commit 9f514f8c04
12 changed files with 80 additions and 101 deletions

View File

@ -13,8 +13,11 @@
"author": "",
"license": "ISC",
"dependencies": {
"@s-libs/micro-dash": "^16.1.0",
"commander": "^11.1.0",
"devcert": "^1.2.2",
"ftp-srv": "github:pockethost/ftp-srv#0fc708bae0d5d7a55ce948767f082d6fcfb2af59",
"pocketbase": "^0.21.3",
"pockethost": "workspace:^"
},
"devDependencies": {

View File

@ -0,0 +1,7 @@
# PocketHost FTP Server plugin
Prerequisites:
- FTP requires instance data to be accessible via the file system. You must run a plugin that implements the `onDataRootFilter`:
- `@pockethost/plugin-launcher-spawn`
-

View File

@ -1,3 +1,4 @@
import { map } from '@s-libs/micro-dash'
import {
Mode,
constants,
@ -8,16 +9,8 @@ import {
} from 'fs'
import { FileStat, FileSystem, FtpConnection } from 'ftp-srv'
import { isAbsolute, join, normalize, resolve, sep } from 'path'
import {
DATA_ROOT,
InstanceFields,
Logger,
PocketBase,
assert,
compact,
map,
newId,
} from 'pockethost/core'
import PocketBase from 'pocketbase'
import { InstanceFields, Logger, assert } from 'pockethost'
import {
FolderNamesMap,
INSTANCE_ROOT_VIRTUAL_FOLDER_NAMES,
@ -51,9 +44,13 @@ export class PhFs implements FileSystem {
private _root: string
client: PocketBase
constructor(connection: FtpConnection, client: PocketBase, logger: Logger) {
constructor(
connection: FtpConnection,
client: PocketBase,
logger: Logger,
root: string,
) {
const cwd = `/`
const root = DATA_ROOT()
this.connection = connection
this.client = client
this.log = logger.create(`PhFs`)

View File

@ -1,13 +1,7 @@
import { keys, values } from '@s-libs/micro-dash'
import { readFileSync } from 'fs'
import { FtpSrv } from 'ftp-srv'
import { keys, values } from 'pockethost/core'
import {
LoggerService,
PocketBase,
PocketHostFilter,
filter,
mkSingleton,
} from 'pockethost/src/common'
import { LoggerService, mkSingleton } from 'pockethost/src/common'
import { asyncExitHook } from 'pockethost/src/core'
import {
PASV_IP,
@ -16,7 +10,7 @@ import {
PORT,
SSL_CERT,
SSL_KEY,
} from '../..'
} from '../../constants'
import { PhFs } from './PhFs'
export type FtpConfig = {}

View File

@ -1,9 +1,7 @@
import { LoggerService } from 'pockethost/core'
import { info } from '../../log'
import { ftpService } from '../FtpService'
export async function ftp() {
const logger = LoggerService().create(`EdgeFtpCommand`)
const { dbg, error, info, warn } = logger
info(`Starting`)
await ftpService({})

View File

@ -1,4 +1,4 @@
import { Command } from 'pockethost/core'
import { Command } from 'commander'
import { ftp } from './ftp'
type Options = {

View File

@ -1,4 +1,4 @@
import { Command } from 'pockethost/core'
import { Command } from 'commander'
import { ServeCommand } from './ServeCommand'
type Options = {

View File

@ -0,0 +1,26 @@
import { join } from 'path'
import { PH_HOME, Settings, mkNumber, mkPath, mkString } from 'pockethost/core'
const PLUGIN_NAME = `plugin-ftp-server`
export const _HOME_DIR =
process.env.PH_FIREWALL_HOME || join(PH_HOME(), PLUGIN_NAME)
export const TLS_PFX = `tls`
const settings = Settings({
PH_FTP_HOME: mkPath(_HOME_DIR, { create: true }),
PH_FTP_PORT: mkNumber(21),
PH_FTP_SSL_KEY: mkPath(join(_HOME_DIR, `${TLS_PFX}.key`)),
PH_FTP_SSL_CERT: mkPath(join(_HOME_DIR, `${TLS_PFX}.cert`)),
PH_FTP_PASV_IP: mkString(`0.0.0.0`),
PH_FTP_PASV_PORT_MIN: mkNumber(10000),
PH_FTP_PASV_PORT_MAX: mkNumber(20000),
})
export const PORT = () => settings.PH_FTP_PORT
export const SSL_KEY = () => settings.PH_FTP_SSL_KEY
export const SSL_CERT = () => settings.PH_FTP_SSL_CERT
export const PASV_IP = () => settings.PH_FTP_PASV_IP
export const PASV_PORT_MIN = () => settings.PH_FTP_PASV_PORT_MIN
export const PASV_PORT_MAX = () => settings.PH_FTP_PASV_PORT_MAX

View File

@ -1,59 +1,10 @@
import devcert from 'devcert'
import { mkdirSync, writeFileSync } from 'fs'
import { join } from 'path'
import {
APEX_DOMAIN,
Command,
IS_DEV,
PH_HOME,
PocketHostAction,
PocketHostFilter,
PocketHostPlugin,
Settings,
mkNumber,
mkPath,
mkString,
} from 'pockethost/core'
import { FtpCommand } from './FtpCommand'
import { PH_HOME } from 'pockethost/core'
import { plugin } from './plugin'
const _HOME_DIR =
export const _HOME_DIR =
process.env.PH_FIREWALL_HOME || join(PH_HOME(), `plugin-ftp-server`)
const TLS_PFX = `tls`
const settings = Settings({
PH_FTP_HOME: mkPath(_HOME_DIR, { create: true }),
PH_FTP_PORT: mkNumber(21),
PH_FTP_SSL_KEY: mkPath(join(_HOME_DIR, `${TLS_PFX}.key`)),
PH_FTP_SSL_CERT: mkPath(join(_HOME_DIR, `${TLS_PFX}.cert`)),
PH_FTP_PASV_IP: mkString(`0.0.0.0`),
PH_FTP_PASV_PORT_MIN: mkNumber(10000),
PH_FTP_PASV_PORT_MAX: mkNumber(20000),
})
export const PORT = () => settings.PH_FTP_PORT
export const SSL_KEY = () => settings.PH_FTP_SSL_KEY
export const SSL_CERT = () => settings.PH_FTP_SSL_CERT
export const PASV_IP = () => settings.PH_FTP_PASV_IP
export const PASV_PORT_MIN = () => settings.PH_FTP_PASV_PORT_MIN
export const PASV_PORT_MAX = () => settings.PH_FTP_PASV_PORT_MAX
const plugin: PocketHostPlugin = async ({ registerAction, registerFilter }) => {
registerFilter(
PocketHostFilter.Core_CliCommands,
async (commands: Command[]) => {
return [...commands, FtpCommand()]
},
)
registerAction(PocketHostAction.Core_Init, async () => {
if (IS_DEV()) {
mkdirSync(_HOME_DIR, { recursive: true })
const { key, cert } = await devcert.certificateFor(APEX_DOMAIN(), {})
writeFileSync(SSL_KEY(), key)
writeFileSync(SSL_CERT(), cert)
}
})
}
export const TLS_PFX = `tls`
export default plugin

View File

@ -0,0 +1,4 @@
import { LoggerService } from 'pockethost'
const logger = LoggerService().create('plugin-ftp-server')
export const { dbg, info } = logger

View File

@ -0,0 +1,20 @@
import devcert from 'devcert'
import { mkdirSync, writeFileSync } from 'fs'
import { IS_DEV, PocketHostPlugin, onCliCommandsFilter } from 'pockethost'
import { APEX_DOMAIN } from 'pockethost/core'
import { _HOME_DIR } from '.'
import { FtpCommand } from './FtpCommand'
import { SSL_CERT, SSL_KEY } from './constants'
export const plugin: PocketHostPlugin = async ({}) => {
onCliCommandsFilter(async (commands) => {
return [...commands, FtpCommand()]
})
if (IS_DEV()) {
mkdirSync(_HOME_DIR, { recursive: true })
const { key, cert } = await devcert.certificateFor(APEX_DOMAIN(), {})
writeFileSync(SSL_KEY(), key)
writeFileSync(SSL_CERT(), cert)
}
}

23
pnpm-lock.yaml generated
View File

@ -117,28 +117,6 @@ importers:
specifier: ^5.4.5
version: 5.4.5
packages/plugin-foo:
dependencies:
commander:
specifier: ^11.1.0
version: 11.1.0
immer:
specifier: ^10.1.1
version: 10.1.1
inflection:
specifier: ^3.0.0
version: 3.0.0
pockethost:
specifier: workspace:^1.5.0
version: link:../pockethost
devDependencies:
'@types/node':
specifier: ^20.8.10
version: 20.14.2
typescript:
specifier: ^5.4.5
version: 5.4.5
packages/plugin-launcher-spawn:
dependencies:
'@types/node':
@ -1975,6 +1953,7 @@ packages:
inflight@1.0.6:
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
inherits@2.0.4:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}