mirror of
https://github.com/pockethost/pockethost.git
synced 2025-03-30 15:08:30 +00:00
Merge branch 'master' of github.com:benallfree/pockethost
This commit is contained in:
commit
0f977f84e6
@ -1,6 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"typeRoots": ["./types"]
|
||||
}
|
||||
}
|
55
src/instance-app/pb_hooks/_ph_admin_sync.pb.js
Normal file
55
src/instance-app/pb_hooks/_ph_admin_sync.pb.js
Normal file
@ -0,0 +1,55 @@
|
||||
onAfterBootstrap((e) => {
|
||||
const dao = $app.dao()
|
||||
const { mkLog } = /** @type {Lib} */ (require(`${__hooks}/_ph_lib.js`))
|
||||
|
||||
const log = mkLog(`admin-sync`)
|
||||
|
||||
const { email, tokenKey, passwordHash } = JSON.parse($os.getenv(`ADMIN_SYNC`))
|
||||
|
||||
if (!email) {
|
||||
log(`Not active - skipped`)
|
||||
}
|
||||
|
||||
const result = new DynamicModel({
|
||||
// describe the shape of the data (used also as initial values)
|
||||
id: '',
|
||||
})
|
||||
|
||||
try {
|
||||
dao
|
||||
.db()
|
||||
.newQuery('SELECT * from _admins where email = {:email}')
|
||||
.bind({ email })
|
||||
.one(result)
|
||||
log(
|
||||
`Existing admin record matching PocketHost login found - updating with latest credentials`,
|
||||
)
|
||||
try {
|
||||
dao
|
||||
.db()
|
||||
.newQuery(
|
||||
'update _admins set tokenKey={:tokenKey}, passwordHash={:passwordHash} where email={:email}',
|
||||
)
|
||||
.bind({ email, tokenKey, passwordHash })
|
||||
.execute()
|
||||
log(`Success`)
|
||||
} catch (e) {
|
||||
log(`Failed to update admin credentials: ${e}`)
|
||||
}
|
||||
} catch (e) {
|
||||
log(`No admin record matching PocketHost credentials - creating`)
|
||||
|
||||
try {
|
||||
dao
|
||||
.db()
|
||||
.newQuery(
|
||||
'insert into _admins (email, tokenKey, passwordHash) VALUES ({:email}, {:tokenKey}, {:passwordHash})',
|
||||
)
|
||||
.bind({ email, tokenKey, passwordHash })
|
||||
.execute()
|
||||
log(`Success`)
|
||||
} catch (e) {
|
||||
log(`Failed to insert admin credentials: ${e}`)
|
||||
}
|
||||
}
|
||||
})
|
19
src/instance-app/pb_hooks/_ph_lib.js
Normal file
19
src/instance-app/pb_hooks/_ph_lib.js
Normal file
@ -0,0 +1,19 @@
|
||||
/** @type {Lib['mkLog']} */
|
||||
const mkLog =
|
||||
(namespace) =>
|
||||
/**
|
||||
* @param {...any} s
|
||||
* @returns
|
||||
*/
|
||||
(...s) =>
|
||||
console.log(
|
||||
`[${namespace}]`,
|
||||
...s.map((p) => {
|
||||
if (typeof p === 'object') return JSON.stringify(p, null, 2)
|
||||
return p
|
||||
}),
|
||||
)
|
||||
|
||||
module.exports = {
|
||||
mkLog,
|
||||
}
|
8
src/instance-app/tsconfig.json
Normal file
8
src/instance-app/tsconfig.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"noImplicitAny": false,
|
||||
"strictNullChecks": false
|
||||
},
|
||||
"include": ["pb_hooks", "types"]
|
||||
}
|
5
src/instance-app/types/lib.d.ts
vendored
Normal file
5
src/instance-app/types/lib.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
type Logger = (...args: any[]) => void
|
||||
|
||||
interface Lib {
|
||||
mkLog: (namespace: string) => Logger
|
||||
}
|
10400
src/instance-app/types/types.d.ts
vendored
10400
src/instance-app/types/types.d.ts
vendored
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,6 @@ import {
|
||||
EDGE_APEX_DOMAIN,
|
||||
INSTANCE_APP_HOOK_DIR,
|
||||
INSTANCE_APP_MIGRATIONS_DIR,
|
||||
INSTANCE_DATA_DB,
|
||||
mkAppUrl,
|
||||
mkContainerHomePath,
|
||||
mkDocUrl,
|
||||
@ -16,7 +15,7 @@ import {
|
||||
PocketbaseService,
|
||||
PortService,
|
||||
proxyService,
|
||||
SqliteService,
|
||||
SpawnConfig,
|
||||
} from '$services'
|
||||
import {
|
||||
assertTruthy,
|
||||
@ -34,6 +33,7 @@ import { asyncExitHook, mkInternalUrl, now } from '$util'
|
||||
import { flatten, map, values } from '@s-libs/micro-dash'
|
||||
import Bottleneck from 'bottleneck'
|
||||
import { globSync } from 'glob'
|
||||
import stringify from 'json-stringify-safe'
|
||||
import { basename, join } from 'path'
|
||||
import { ClientResponseError } from 'pocketbase'
|
||||
import { AsyncReturnType } from 'type-fest'
|
||||
@ -248,6 +248,34 @@ export const instanceService = mkSingleton(
|
||||
})
|
||||
healthyGuard()
|
||||
|
||||
/** Create spawn config */
|
||||
const spawnArgs: SpawnConfig = {
|
||||
subdomain: instance.subdomain,
|
||||
instanceId: instance.id,
|
||||
port: newPort,
|
||||
dev: instance.dev,
|
||||
extraBinds: flatten([
|
||||
globSync(join(INSTANCE_APP_MIGRATIONS_DIR(), '*.js')).map(
|
||||
(file) =>
|
||||
`${file}:${mkContainerHomePath(
|
||||
`pb_migrations/${basename(file)}`,
|
||||
)}:ro`,
|
||||
),
|
||||
globSync(join(INSTANCE_APP_HOOK_DIR(), '*.js')).map(
|
||||
(file) =>
|
||||
`${file}:${mkContainerHomePath(
|
||||
`pb_hooks/${basename(file)}`,
|
||||
)}:ro`,
|
||||
),
|
||||
]),
|
||||
env: {
|
||||
...instance.secrets,
|
||||
PH_APP_NAME: instance.subdomain,
|
||||
PH_INSTANCE_URL: mkEdgeUrl(instance.subdomain),
|
||||
},
|
||||
version,
|
||||
}
|
||||
|
||||
/** Sync admin account */
|
||||
if (instance.syncAdmin) {
|
||||
const id = instance.uid
|
||||
@ -255,36 +283,11 @@ export const instanceService = mkSingleton(
|
||||
const { email, tokenKey, passwordHash } =
|
||||
await client.getUserTokenInfo({ id })
|
||||
dbg(`Token info is`, { email, tokenKey, passwordHash })
|
||||
const sqliteService = await SqliteService()
|
||||
const db = await sqliteService.getDatabase(
|
||||
INSTANCE_DATA_DB(instance.id),
|
||||
)
|
||||
userInstanceLogger.info(`Syncing admin login`)
|
||||
try {
|
||||
// First, try upserting
|
||||
await db(`_admins`)
|
||||
.insert({ id, email, tokenKey, passwordHash })
|
||||
.onConflict('id')
|
||||
.merge({ email, tokenKey, passwordHash })
|
||||
|
||||
userInstanceLogger.info(`${email} has been successfully sync'd`)
|
||||
} catch (e) {
|
||||
// Upsert could fail if the email exists under a different ID
|
||||
// If that happens, it means they created an admin account with the same email
|
||||
// manually. In that case, just update the pw hash
|
||||
try {
|
||||
userInstanceLogger.info(`Got an error on admin sync upsert. ${e}`)
|
||||
userInstanceLogger.info(
|
||||
`${email} may already exist under a different ID, trying to update instead`,
|
||||
)
|
||||
await db(`_admins`)
|
||||
.update({ tokenKey, passwordHash })
|
||||
.where({ email })
|
||||
userInstanceLogger.info(`${email} has been successfully sync'd`)
|
||||
} catch (e) {
|
||||
userInstanceLogger.error(`Failed to sync admin account: ${e}`)
|
||||
}
|
||||
}
|
||||
spawnArgs.env!.ADMIN_SYNC = stringify({
|
||||
email,
|
||||
tokenKey,
|
||||
passwordHash,
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
@ -292,32 +295,7 @@ export const instanceService = mkSingleton(
|
||||
*/
|
||||
const childProcess = await (async () => {
|
||||
try {
|
||||
const cp = await pbService.spawn({
|
||||
subdomain: instance.subdomain,
|
||||
instanceId: instance.id,
|
||||
port: newPort,
|
||||
dev: instance.dev,
|
||||
extraBinds: flatten([
|
||||
globSync(join(INSTANCE_APP_MIGRATIONS_DIR(), '*.js')).map(
|
||||
(file) =>
|
||||
`${file}:${mkContainerHomePath(
|
||||
`pb_migrations/${basename(file)}`,
|
||||
)}:ro`,
|
||||
),
|
||||
globSync(join(INSTANCE_APP_HOOK_DIR(), '*.js')).map(
|
||||
(file) =>
|
||||
`${file}:${mkContainerHomePath(
|
||||
`pb_hooks/${basename(file)}`,
|
||||
)}:ro`,
|
||||
),
|
||||
]),
|
||||
env: {
|
||||
...instance.secrets,
|
||||
PH_APP_NAME: instance.subdomain,
|
||||
PH_INSTANCE_URL: mkEdgeUrl(instance.subdomain),
|
||||
},
|
||||
version,
|
||||
})
|
||||
const cp = await pbService.spawn(spawnArgs)
|
||||
|
||||
return cp
|
||||
} catch (e) {
|
||||
|
@ -24,6 +24,5 @@
|
||||
"$shared": ["src/shared"]
|
||||
}
|
||||
},
|
||||
"include": ["./src"],
|
||||
"exclude": ["src/instance-app"]
|
||||
"include": ["./src"]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user