Merge branch 'master' of github.com:benallfree/pockethost

This commit is contained in:
Ben Allfree 2024-01-13 12:56:16 +00:00
commit 0f977f84e6
8 changed files with 6501 additions and 4089 deletions

View File

@ -1,6 +0,0 @@
{
"compilerOptions": {
"baseUrl": ".",
"typeRoots": ["./types"]
}
}

View 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}`)
}
}
})

View 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,
}

View 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
View File

@ -0,0 +1,5 @@
type Logger = (...args: any[]) => void
interface Lib {
mkLog: (namespace: string) => Logger
}

File diff suppressed because it is too large Load Diff

View File

@ -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) {

View File

@ -24,6 +24,5 @@
"$shared": ["src/shared"]
}
},
"include": ["./src"],
"exclude": ["src/instance-app"]
"include": ["./src"]
}