shared/platform-tools was a git submodule. On this branch it is a plain
directory of tracked files, frozen at ea3616abae30106df283e73a3e2f9e5bb0e6ae90
— the same commit fotografia.andmore.pt pins. Contents are byte-identical to
that tree, verified blob by blob.
The submodule caused every deployment failure this site has had:
- .gitmodules named no `branch`, so the update fell back to
refs/remotes/origin/HEAD — a ref a plain server-side clone never writes.
"Atualizar submódulo" failed with "Unable to find refs/remotes/origin/HEAD
revision in submodule path".
- Its URL was http://, which the origin answers with 523.
- This install is deployed by uploading files, and a submodule is invisible
to that. The tree moved forward while shared/platform-tools stayed on the
old pin, config/functions_secrets.php died on a missing compat_secrets.php,
and the whole site — public pages included — went down.
Each of those was separately fixable. Together they mean a second repository
nobody can see from the deployment path, gating whether the first one boots. A
plain directory deploys like every other file and cannot fall out of step.
The cost is that platform-tools updates no longer arrive by bumping a pin; they
are a copy-over-and-commit. shared/platform-tools/VENDORED.md records the
upstream SHA, the procedure, and which four files differ from upstream in line
endings only (social/*.js, .css, functions_publications.php — CRLF upstream,
normalised to LF here; content otherwise identical).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
48 lines
2.0 KiB
PHP
48 lines
2.0 KiB
PHP
<?php
|
|
// Emparelhamento: o hub chama aqui quando o André aprova esta plataforma na
|
|
// Frota. É a ÚNICA etapa em que as chaves saem daqui, e saem numa ligação que o
|
|
// hub iniciou — não numa que esta plataforma abriu para um URL que lhe deram.
|
|
//
|
|
// Autenticação: o código de emparelhamento que esta plataforma gerou e enviou
|
|
// no anúncio. Uso único, com validade. Não há chave de API nesta etapa, porque
|
|
// é precisamente ela que está a ser entregue.
|
|
//
|
|
// O stub de cada site (public/api/hub_pair.php) é uma linha a incluir isto.
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/../hub_bootstrap.php';
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
hub_json(['ok' => false, 'error' => 'usa POST'], 405);
|
|
}
|
|
|
|
$req = json_decode((string) file_get_contents('php://input'), true);
|
|
$code = is_array($req) ? (string) ($req['pairing_code'] ?? '') : '';
|
|
$ops = is_array($req) && !empty($req['with_ops']);
|
|
|
|
if ($code === '') hub_json(['ok' => false, 'error' => 'código em falta'], 400);
|
|
|
|
// O emparelhamento automático guarda o estado e as chaves no system_settings,
|
|
// portanto precisa mesmo de base de dados. Uma montra estática (ver a nota do
|
|
// hub_bootstrap.php) inscreve-se à mão: chaves no .env do stack, linha na
|
|
// tabela `apps` do hub. Diz-se isso, em vez de rebentar sobre um $pdo a null.
|
|
if (!$pdo instanceof PDO) {
|
|
hub_json(['ok' => false,
|
|
'error' => 'plataforma sem base de dados — inscreve-se à mão, com as chaves no .env'], 400);
|
|
}
|
|
|
|
$res = hub_pair_complete($pdo, $code, $ops);
|
|
if (empty($res['ok'])) {
|
|
// 403 e não 404: o pedido chegou ao sítio certo, o que falha é a permissão.
|
|
hub_json(['ok' => false, 'error' => $res['error']], 403);
|
|
}
|
|
|
|
hub_json([
|
|
'ok' => true,
|
|
'app' => hub_app_name(),
|
|
'api_key' => $res['api_key'],
|
|
'ops_key' => $res['ops_key'], // null quando o hub não pediu operações
|
|
'health' => hub_base_url('api/health.php'),
|
|
'ops' => hub_base_url('api/hub_ops.php'),
|
|
]);
|