feat(store,doctor): surface the hub's trust + exposure data (0.77.0)
Some checks failed
Security / Security check (push) Failing after 1s
Some checks failed
Security / Security check (push) Failing after 1s
The trust-gate dialog replaces its generic 'no per-entry status yet (alpha)' note with the hub's classified verification statement — pinned store key / trusted publishers (green), installs without signature checking (amber), install would be refused (red), bridge entry (neutral) — via one shared describeInstallVerification mapping. Against a pre-0.23 hub the field is empty and the old honest wording stays (pinned by test). Information architecture: policy-off is a GLOBAL fact, so it appears as ONE ChainInlineHelp notice above the store grid instead of a warning pill on every card (card noise); only 'blocked' — a genuine per-source anomaly — earns a card pill. Doctor's host services show the hub-classified network reach per endpoint (local only / private network / publicly reachable with a protect-it hint / reach unknown). Verified end-to-end against the live dev hub (guide harness): the wire field arrives, the store page shows exactly one policy notice and quiet cards; trust-gate variants captured via the dialog harness. Suite 123 green. Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
parent
87afa4dc05
commit
2f076ccf29
15 changed files with 732 additions and 13 deletions
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
/// Studio's own build version. Bump on every UI release so the
|
||||
/// running app self-identifies.
|
||||
const String kStudioVersion = '0.76.0';
|
||||
const String kStudioVersion = '0.77.0';
|
||||
|
||||
const String kProductName = 'Ch∆In Studio';
|
||||
const String kVendorName = 'Flemming.AI (F∆I)';
|
||||
|
|
|
|||
|
|
@ -937,6 +937,7 @@ class HubService {
|
|||
source: e.source,
|
||||
canonicalCategory: e.canonicalCategory,
|
||||
canonicalCategoryLabel: e.canonicalCategoryLabel,
|
||||
installVerification: e.installVerification,
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
|
|
@ -1289,7 +1290,12 @@ class HubService {
|
|||
services: services
|
||||
.map(
|
||||
(s) =>
|
||||
ServiceEntry(name: s.name, endpoint: s.endpoint, tags: s.tags),
|
||||
ServiceEntry(
|
||||
name: s.name,
|
||||
endpoint: s.endpoint,
|
||||
tags: s.tags,
|
||||
exposure: s.exposure,
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
update: UpdateStatus(
|
||||
|
|
@ -1386,10 +1392,16 @@ class ServiceEntry {
|
|||
final String endpoint;
|
||||
final List<String> tags;
|
||||
|
||||
/// Network reach of [endpoint] as classified by the hub
|
||||
/// (host part only, no DNS): "loopback" / "private" / "public" /
|
||||
/// "unknown". Empty from pre-0.23 hubs.
|
||||
final String exposure;
|
||||
|
||||
const ServiceEntry({
|
||||
required this.name,
|
||||
required this.endpoint,
|
||||
required this.tags,
|
||||
this.exposure = '',
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -2233,6 +2245,15 @@ class StoreItem {
|
|||
/// Human-readable label for [canonicalCategory] (e.g. "Data & Formats").
|
||||
final String canonicalCategoryLabel;
|
||||
|
||||
/// How an install of this entry would be verified under the
|
||||
/// hub's CURRENT policy — computed hub-side with the same
|
||||
/// resolvers the install gate enforces, so this can never
|
||||
/// disagree with what actually happens:
|
||||
/// "pinned-key" / "trusted-publishers" / "unverified" /
|
||||
/// "blocked" / "federated". Empty from pre-0.23 hubs — the UI
|
||||
/// keeps its generic note then.
|
||||
final String installVerification;
|
||||
|
||||
/// True iff this entry is a Studio plugin/theme rather than a flow
|
||||
/// module — drives the "Modules | Studio & Themes" store segment.
|
||||
bool get isStudioPlugin => canonicalCategory == 'studio-themes';
|
||||
|
|
@ -2264,5 +2285,6 @@ class StoreItem {
|
|||
this.source = '',
|
||||
this.canonicalCategory = '',
|
||||
this.canonicalCategoryLabel = '',
|
||||
this.installVerification = '',
|
||||
});
|
||||
}
|
||||
|
|
|
|||
65
lib/data/install_verification.dart
Normal file
65
lib/data/install_verification.dart
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
// Presentation of `StoreItem.installVerification` — the hub's
|
||||
// per-entry statement of how an install would be verified under
|
||||
// the CURRENT policy (computed hub-side with the same resolvers
|
||||
// the install gate enforces). One mapping, used by the trust-gate
|
||||
// dialog, the module detail sheet and the store card, so every
|
||||
// surface tells the same story.
|
||||
|
||||
import '../l10n/app_localizations.dart';
|
||||
|
||||
enum VerificationTone { good, neutral, warning, danger }
|
||||
|
||||
class InstallVerificationInfo {
|
||||
final String label;
|
||||
final String body;
|
||||
final VerificationTone tone;
|
||||
|
||||
const InstallVerificationInfo({
|
||||
required this.label,
|
||||
required this.body,
|
||||
required this.tone,
|
||||
});
|
||||
}
|
||||
|
||||
/// Maps the wire value to its localized presentation. Returns null
|
||||
/// for an empty/unknown value (pre-0.23 hub) — callers keep their
|
||||
/// generic wording then instead of guessing.
|
||||
InstallVerificationInfo? describeInstallVerification(
|
||||
String wire,
|
||||
AppLocalizations l,
|
||||
) {
|
||||
switch (wire) {
|
||||
case 'pinned-key':
|
||||
return InstallVerificationInfo(
|
||||
label: l.verifPinnedKey,
|
||||
body: l.verifPinnedKeyBody,
|
||||
tone: VerificationTone.good,
|
||||
);
|
||||
case 'trusted-publishers':
|
||||
return InstallVerificationInfo(
|
||||
label: l.verifTrustedPublishers,
|
||||
body: l.verifTrustedPublishersBody,
|
||||
tone: VerificationTone.good,
|
||||
);
|
||||
case 'unverified':
|
||||
return InstallVerificationInfo(
|
||||
label: l.verifUnverified,
|
||||
body: l.verifUnverifiedBody,
|
||||
tone: VerificationTone.warning,
|
||||
);
|
||||
case 'blocked':
|
||||
return InstallVerificationInfo(
|
||||
label: l.verifBlocked,
|
||||
body: l.verifBlockedBody,
|
||||
tone: VerificationTone.danger,
|
||||
);
|
||||
case 'federated':
|
||||
return InstallVerificationInfo(
|
||||
label: l.verifFederated,
|
||||
body: l.verifFederatedBody,
|
||||
tone: VerificationTone.neutral,
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue