feat: add remote trust and server identity pinning
Testing / remote-protocol-compat (0.16.0) (push) Successful in 1m1s
Testing / remote-protocol-compat (0.15.0) (push) Successful in 1m3s
Testing / test (push) Failing after 1m15s
Build & Publish Package / publish (push) Successful in 51s
Package Extension / package-extension (push) Successful in 1m6s
Testing / remote-protocol-compat (0.16.0) (push) Successful in 1m1s
Testing / remote-protocol-compat (0.15.0) (push) Successful in 1m3s
Testing / test (push) Failing after 1m15s
Build & Publish Package / publish (push) Successful in 51s
Package Extension / package-extension (push) Successful in 1m6s
- Add SSH-style server identity keys and known-host verification for remote serve endpoints. - Add remote add/list/remove commands for explicit endpoint persistence. - Fix remote clients listing to fan out through target discovery instead of ambiguous auto-routing. - Add URL glob matching for tabs filter and count with extension tests. - Add n8n credential pinning for server public keys or SHA256 fingerprints. - Remove obsolete compat shim behavior while keeping empty compat seams for future protocol changes. - Bump browser-cli to 0.16.4 and n8n node to 0.3.1. - Cover known-hosts, remote registry, compat seams, n8n protocol verification, and URL matching with tests.
This commit is contained in:
@@ -4,6 +4,26 @@ import { CommandGroup } from '../classes/CommandGroup';
|
||||
import type { CommandEntry } from '../classes/CommandGroup';
|
||||
import type { TabIdArgs, TabsActiveInWindowArgs, TabsPatternArgs, TabsQueryArgs, TabsWatchUrlArgs } from '../types';
|
||||
|
||||
/** Convert a shell-style glob (`*` = any run, `?` = any single char) to an
|
||||
* unanchored RegExp. Every other character is matched literally. Unanchored so
|
||||
* `twitch.tv/*` matches anywhere inside `https://www.twitch.tv/foo`. */
|
||||
function globToRegExp(glob: string): RegExp {
|
||||
const escaped = glob.replace(/[.+^${}()|[\]\\]/g, '\\$&');
|
||||
return new RegExp(escaped.replace(/\*/g, '.*').replace(/\?/g, '.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Match a tab URL against a pattern. Backward-compatible: a pattern with no
|
||||
* glob metacharacters is a plain case-sensitive substring match (the historic
|
||||
* behavior); a pattern containing `*` or `?` is treated as a glob, so
|
||||
* `twitch.tv/*` matches every Twitch tab.
|
||||
*/
|
||||
export function urlMatchesPattern(url: string | undefined, pattern: string): boolean {
|
||||
if (!url || !pattern) return false;
|
||||
if (/[*?]/.test(pattern)) return globToRegExp(pattern).test(url);
|
||||
return url.includes(pattern);
|
||||
}
|
||||
|
||||
export class TabsQueryCommands extends CommandGroup {
|
||||
readonly namespace = "tabs";
|
||||
readonly commands: Record<string, CommandEntry> = {
|
||||
@@ -50,12 +70,12 @@ export class TabsQueryCommands extends CommandGroup {
|
||||
|
||||
private async tabsFilter({ pattern }: TabsPatternArgs) {
|
||||
const all = await api.tabs.query({});
|
||||
return all.filter(t => t.url && t.url.includes(pattern)).map(tabInfo);
|
||||
return all.filter(t => urlMatchesPattern(t.url, pattern)).map(tabInfo);
|
||||
}
|
||||
|
||||
private async tabsCount({ pattern }: TabsPatternArgs) {
|
||||
const all = await api.tabs.query({});
|
||||
if (pattern) return all.filter(t => t.url && t.url.includes(pattern)).length;
|
||||
if (pattern) return all.filter(t => urlMatchesPattern(t.url, pattern)).length;
|
||||
return all.length;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user