mirror of
https://github.com/pockethost/pockethost.git
synced 2025-05-22 14:56:42 +00:00
fix: FTP access to deep subdirectories and pb_migrations
This commit is contained in:
parent
04deecf8fd
commit
a601e53430
@ -17,6 +17,7 @@ export type FtpConfig = {}
|
|||||||
export enum FolderNames {
|
export enum FolderNames {
|
||||||
PbData = 'pb_data',
|
PbData = 'pb_data',
|
||||||
PbStatic = 'pb_static',
|
PbStatic = 'pb_static',
|
||||||
|
PbMigrations = 'pb_migrations',
|
||||||
PbWorker = 'worker',
|
PbWorker = 'worker',
|
||||||
PbBackup = 'backup',
|
PbBackup = 'backup',
|
||||||
}
|
}
|
||||||
@ -26,6 +27,7 @@ export const README_CONTENTS: { [_ in FolderNames]: string } = {
|
|||||||
[FolderNames.PbData]: `This directory contains your PocketBase data. For more information, see https://pockethost.io/docs/data`,
|
[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.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.PbWorker]: `This directory contains your Deno worker. For more information, see https://pockethost.io/docs/workers`,
|
[FolderNames.PbWorker]: `This directory contains your Deno worker. For more information, see https://pockethost.io/docs/workers`,
|
||||||
|
[FolderNames.PbMigrations]: `This directory contains your migrations. For more information, see https://pockethost.io/docs/migrations`,
|
||||||
}
|
}
|
||||||
export const README_NAME = 'readme.md'
|
export const README_NAME = 'readme.md'
|
||||||
|
|
||||||
@ -34,6 +36,7 @@ export const FOLDER_NAMES: FolderNames[] = [
|
|||||||
FolderNames.PbData,
|
FolderNames.PbData,
|
||||||
FolderNames.PbStatic,
|
FolderNames.PbStatic,
|
||||||
FolderNames.PbWorker,
|
FolderNames.PbWorker,
|
||||||
|
FolderNames.PbMigrations,
|
||||||
]
|
]
|
||||||
|
|
||||||
export function isFolder(name: string): name is FolderNames {
|
export function isFolder(name: string): name is FolderNames {
|
||||||
|
@ -47,8 +47,8 @@ export class PhFs extends FileSystem {
|
|||||||
throw new Error(`Expected path`)
|
throw new Error(`Expected path`)
|
||||||
}
|
}
|
||||||
const _path = path.startsWith('/') ? path : join(this.cwd, path)
|
const _path = path.startsWith('/') ? path : join(this.cwd, path)
|
||||||
const [empty, subdomain, folderName] = _path.split('/')
|
const [empty, subdomain, folderName, ...restOfPath] = _path.split('/')
|
||||||
this.log.dbg({ _path, subdomain, folderName })
|
this.log.dbg({ _path, subdomain, folderName, restOfPath })
|
||||||
|
|
||||||
if (subdomain === '') {
|
if (subdomain === '') {
|
||||||
const instances = await this.client.getInstances()
|
const instances = await this.client.getInstances()
|
||||||
@ -62,49 +62,48 @@ export class PhFs extends FileSystem {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (subdomain) {
|
if (!subdomain) {
|
||||||
const [instance, user] = await this.client.getInstanceBySubdomain(
|
throw new Error(`Subdomain expected in ${_path}`)
|
||||||
subdomain
|
|
||||||
)
|
|
||||||
if (!instance) {
|
|
||||||
throw new Error(`Expected instance here`)
|
|
||||||
}
|
|
||||||
if (!folderName) {
|
|
||||||
return FOLDER_NAMES.map((name) => ({
|
|
||||||
isDirectory: () => true,
|
|
||||||
mode: 0o755,
|
|
||||||
size: 0,
|
|
||||||
mtime: Date.parse(instance.updated),
|
|
||||||
name: name,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
if (isFolder(folderName)) {
|
|
||||||
const dir = join(DAEMON_PB_DATA_DIR, instance.id, folderName)
|
|
||||||
this.log.dbg({ dir, exists: existsSync(dir) })
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
isDirectory: () => false,
|
|
||||||
mode: 0o444,
|
|
||||||
size: README_CONTENTS[folderName].length,
|
|
||||||
mtime: Date.parse(instance.updated),
|
|
||||||
name: README_NAME,
|
|
||||||
},
|
|
||||||
...(existsSync(dir)
|
|
||||||
? await super.list(
|
|
||||||
join(DAEMON_PB_DATA_DIR, instance.id, folderName)
|
|
||||||
)
|
|
||||||
: []),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
throw new Error(`Error parsing ${_path}`)
|
const [instance, user] = await this.client.getInstanceBySubdomain(subdomain)
|
||||||
|
if (!instance) {
|
||||||
|
throw new Error(`Expected instance here`)
|
||||||
|
}
|
||||||
|
if (!folderName) {
|
||||||
|
return FOLDER_NAMES.map((name) => ({
|
||||||
|
isDirectory: () => true,
|
||||||
|
mode: 0o755,
|
||||||
|
size: 0,
|
||||||
|
mtime: Date.parse(instance.updated),
|
||||||
|
name: name,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
if (!isFolder(folderName)) {
|
||||||
|
throw new Error(`Top level folder name ${folderName} not allowed.`)
|
||||||
|
}
|
||||||
|
const dir = join(DAEMON_PB_DATA_DIR, instance.id, folderName, ...restOfPath)
|
||||||
|
this.log.dbg({ dir, exists: existsSync(dir) })
|
||||||
|
return [
|
||||||
|
...(restOfPath.length === 0
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
isDirectory: () => false,
|
||||||
|
mode: 0o444,
|
||||||
|
size: README_CONTENTS[folderName].length,
|
||||||
|
mtime: Date.parse(instance.updated),
|
||||||
|
name: README_NAME,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
...(existsSync(dir) ? await super.list(dir) : []),
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
async get(fileName: string): Promise<FileStat> {
|
async get(fileName: string): Promise<FileStat> {
|
||||||
const _path = fileName.startsWith('/') ? fileName : join(this.cwd, fileName)
|
const path = fileName.startsWith('/') ? fileName : join(this.cwd, fileName)
|
||||||
const [empty, subdomain, folderName, ...fNames] = _path.split('/')
|
const [empty, subdomain, folderName, ...fNames] = path.split('/')
|
||||||
const fName = fNames.join('/')
|
const fName = fNames.join('/')
|
||||||
this.log.dbg(`get`, { _path, subdomain, folderName, fName, fileName })
|
this.log.dbg(`get`, { _path: path, subdomain, folderName, fName, fileName })
|
||||||
|
|
||||||
if (!subdomain) {
|
if (!subdomain) {
|
||||||
return {
|
return {
|
||||||
@ -140,7 +139,15 @@ export class PhFs extends FileSystem {
|
|||||||
name: folderName,
|
name: folderName,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return super.get(_path)
|
const physicalPath = join(
|
||||||
|
DAEMON_PB_DATA_DIR,
|
||||||
|
instance.id,
|
||||||
|
folderName,
|
||||||
|
fName
|
||||||
|
)
|
||||||
|
this.log.dbg({ physicalPath, exists: existsSync(physicalPath) })
|
||||||
|
|
||||||
|
return super.get(physicalPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
async write(
|
async write(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user