@vantageos/backend-doctor 0.1.14 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -5
- package/dist/args.d.ts +16 -0
- package/dist/args.js +72 -0
- package/dist/build-stamp.d.ts +13 -0
- package/dist/build-stamp.js +76 -0
- package/dist/build-stamp.json +4 -0
- package/dist/caller-resolution.d.ts +222 -0
- package/dist/caller-resolution.js +1198 -0
- package/dist/cli.js +249 -17
- package/dist/contract.d.ts +25 -7
- package/dist/contract.js +52 -7
- package/dist/coverage-cli.js +8 -0
- package/dist/coverage.d.ts +1 -1
- package/dist/coverage.js +2 -2
- package/dist/detectors/oracle-axis1.d.ts +5 -3
- package/dist/detectors/oracle-axis1.js +28 -18
- package/dist/detectors/oracle-axis2.d.ts +6 -0
- package/dist/detectors/oracle-axis2.js +37 -22
- package/dist/detectors/predicates.d.ts +3 -0
- package/dist/detectors/predicates.js +93 -19
- package/dist/detectors/shared.js +8 -7
- package/dist/detectors/source/_ast.d.ts +92 -0
- package/dist/detectors/source/_ast.js +353 -0
- package/dist/detectors/source/_scan.js +4 -3
- package/dist/detectors/source/backfill.js +71 -18
- package/dist/detectors/source/contract.js +21 -13
- package/dist/detectors/source/cross-tenant-write.d.ts +46 -0
- package/dist/detectors/source/cross-tenant-write.js +1408 -0
- package/dist/detectors/source/guard-helper-flow.d.ts +134 -0
- package/dist/detectors/source/guard-helper-flow.js +1216 -0
- package/dist/detectors/source/identity-by-id.d.ts +80 -0
- package/dist/detectors/source/identity-by-id.js +1783 -0
- package/dist/detectors/source/identity.d.ts +58 -2
- package/dist/detectors/source/identity.js +1158 -28
- package/dist/detectors/source/isolation.d.ts +11 -1
- package/dist/detectors/source/isolation.js +106 -25
- package/dist/detectors/source/jobs.js +178 -4
- package/dist/detectors/source/lifecycle.js +14 -2
- package/dist/detectors/source/local-identity.d.ts +26 -0
- package/dist/detectors/source/local-identity.js +661 -0
- package/dist/detectors/source/package-principal.d.ts +9 -0
- package/dist/detectors/source/package-principal.js +177 -0
- package/dist/detectors/source/r6-shapes.d.ts +20 -0
- package/dist/detectors/source/r6-shapes.js +285 -0
- package/dist/detectors/source/readbudget.d.ts +1 -0
- package/dist/detectors/source/readbudget.js +358 -4
- package/dist/detectors/source/recipient-by-id.d.ts +40 -0
- package/dist/detectors/source/recipient-by-id.js +1108 -0
- package/dist/detectors/source/refusal.d.ts +14 -0
- package/dist/detectors/source/refusal.js +75 -2
- package/dist/detectors/source/security.d.ts +16 -0
- package/dist/detectors/source/security.js +680 -33
- package/dist/detectors/source/write-isolation.d.ts +8 -1
- package/dist/detectors/source/write-isolation.js +64 -30
- package/dist/detectors/source/writesafety.js +27 -14
- package/dist/detectors/standard/_doc.d.ts +1 -1
- package/dist/detectors/standard/_doc.js +5 -4
- package/dist/detectors/standard/r41-frontier.js +3 -2
- package/dist/detectors/standard/r46-returns-validator.d.ts +8 -0
- package/dist/detectors/standard/r46-returns-validator.js +48 -16
- package/dist/detectors/structural.d.ts +6 -7
- package/dist/detectors/structural.js +84 -48
- package/dist/not-checkable.d.ts +1 -1
- package/dist/not-checkable.js +11 -0
- package/dist/oracle.d.ts +92 -3
- package/dist/oracle.js +229 -12
- package/dist/registry.d.ts +8 -1
- package/dist/registry.js +74 -8
- package/dist/report.d.ts +11 -1
- package/dist/report.js +15 -2
- package/dist/rule-class.d.ts +85 -0
- package/dist/rule-class.js +218 -0
- package/dist/state-rank.d.ts +5 -0
- package/dist/state-rank.js +9 -0
- package/dist/tally.d.ts +13 -5
- package/dist/tally.js +15 -13
- package/dist/target.d.ts +32 -0
- package/dist/target.js +173 -0
- package/dist/violation-count.d.ts +48 -0
- package/dist/violation-count.js +94 -0
- package/fixtures/backend-standard-2825122.md +722 -0
- package/fixtures/backend-standard-4dcd3e0.md +722 -0
- package/fixtures/cr1-classes/_generated/api.d.ts +24 -0
- package/fixtures/cr1-classes/surface.ts +206 -0
- package/fixtures/cr1-empty/nothing.ts +1 -0
- package/fixtures/cr1-refusal-on-resolved/_generated/api.d.ts +24 -0
- package/fixtures/cr1-refusal-on-resolved/doors.ts +180 -0
- package/fixtures/cr1-refusal-on-resolved/lib/auth.ts +104 -0
- package/fixtures/r34-vp-auth-30e821b/auth-805-812.ts.txt +8 -0
- package/fixtures/r34-vp-auth-30e821b/auth-878-890.ts.txt +13 -0
- package/fixtures/rule-classes-2825122.json +228 -0
- package/fixtures/vp-writer-tier-1e4ab36.csv +55 -0
- package/package.json +2 -2
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import * as ts from "typescript";
|
|
2
|
+
export type GuardHelperKind = "binds-arg" | "master-only";
|
|
3
|
+
export type HelperVerdict = {
|
|
4
|
+
verdict: "honoured";
|
|
5
|
+
} | {
|
|
6
|
+
verdict: "refused";
|
|
7
|
+
why: string;
|
|
8
|
+
} | {
|
|
9
|
+
verdict: "could-not-judge";
|
|
10
|
+
why: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* SCOPE REFINERS, by name: a call `await R(ctx, <scope>, …)` whose result is
|
|
14
|
+
* scope-derived exactly when the scope it is handed (at `argIndex`) is. The
|
|
15
|
+
* refiner returns that scope unchanged, or rebuilds it from a SERVER-SIDE row
|
|
16
|
+
* after refusing every transport but the fleet service account — vantage-peers
|
|
17
|
+
* `convex/lib/personPrincipal.ts::resolveVerifiedPerson` (the `verifiedPerson`
|
|
18
|
+
* proof is believed from the service account only and the person's scope is
|
|
19
|
+
* re-read from `oauth_access_tokens`). The other arguments it is handed (a
|
|
20
|
+
* proof, a door name, an asserted name) never become its return.
|
|
21
|
+
*
|
|
22
|
+
* Trusted by NAME, on the same footing as `withOrgScope` in isIdentityRead: the
|
|
23
|
+
* flow walk cannot model "a scope rebuilt from a stored row" as the identity.
|
|
24
|
+
* The trust is narrow — the result is pure only when the scope argument itself
|
|
25
|
+
* is pure; a refiner handed anything else confers nothing.
|
|
26
|
+
*/
|
|
27
|
+
export declare const SCOPE_REFINERS: Readonly<Record<string, {
|
|
28
|
+
argIndex: number;
|
|
29
|
+
}>>;
|
|
30
|
+
/** A callee name, as seen from the function being judged, resolved to its
|
|
31
|
+
* definition in the tree (and to a resolver for names seen from THAT file). */
|
|
32
|
+
export type CallResolver = (name: string) => {
|
|
33
|
+
fn: ts.FunctionLikeDeclaration;
|
|
34
|
+
key: string;
|
|
35
|
+
resolve: CallResolver;
|
|
36
|
+
} | undefined;
|
|
37
|
+
/** Judge one helper function on its control flow. */
|
|
38
|
+
export declare function judgeHelperFunction(fn: ts.FunctionLikeDeclaration, kind: GuardHelperKind): HelperVerdict;
|
|
39
|
+
export interface FoundHelper {
|
|
40
|
+
name: string;
|
|
41
|
+
line: number;
|
|
42
|
+
exported: boolean;
|
|
43
|
+
judgement: HelperVerdict;
|
|
44
|
+
}
|
|
45
|
+
/** Every definition, in `source`, of a helper named in `kinds`. */
|
|
46
|
+
export declare function findHelperDefinitions(fileName: string, source: string, kinds: Readonly<Record<string, GuardHelperKind>>): FoundHelper[];
|
|
47
|
+
/** The arguments of each `await <helper>(…)` that is a DIRECT statement of the
|
|
48
|
+
* handler `name` (`export const name = mutation({ handler: … })`) and starts
|
|
49
|
+
* before `beforeLine`. A helper call nested in a branch, a try, or a closure of
|
|
50
|
+
* the handler is not a statement every path runs, so it is not returned.
|
|
51
|
+
* `null` = the handler's body could not be located in the file. */
|
|
52
|
+
export declare function topLevelHelperCalls(fileName: string, source: string, handlerName: string,
|
|
53
|
+
/** `null` = any identifier callee (judged by the caller on its body). */
|
|
54
|
+
helpers: ReadonlySet<string> | null, beforeLine: number): {
|
|
55
|
+
name: string;
|
|
56
|
+
args: string;
|
|
57
|
+
argNodes: readonly ts.Expression[];
|
|
58
|
+
line: number;
|
|
59
|
+
}[] | null;
|
|
60
|
+
export interface TopLevelFunction {
|
|
61
|
+
name: string;
|
|
62
|
+
line: number;
|
|
63
|
+
exported: boolean;
|
|
64
|
+
fn: ts.FunctionLikeDeclaration;
|
|
65
|
+
}
|
|
66
|
+
/** Every top-level function declaration and `const f = (…) => {…}` /
|
|
67
|
+
* `function (…) {…}` of a file. */
|
|
68
|
+
export declare function topLevelFunctions(fileName: string, source: string): TopLevelFunction[];
|
|
69
|
+
/** Judge a function as an IDENTITY RESOLVER (shape 1 above). */
|
|
70
|
+
export declare function judgeResolverFunction(fn: ts.FunctionLikeDeclaration): HelperVerdict;
|
|
71
|
+
export type ValidatorSummary = {
|
|
72
|
+
ok: false;
|
|
73
|
+
why: string;
|
|
74
|
+
} | {
|
|
75
|
+
ok: true;
|
|
76
|
+
/** every normal exit binds the target parameter (or is the master's) */
|
|
77
|
+
exitsBound: boolean;
|
|
78
|
+
/** every normal exit is the fleet master's */
|
|
79
|
+
exitsMaster: boolean;
|
|
80
|
+
/** no normal exit at all: it refuses every caller */
|
|
81
|
+
never: boolean;
|
|
82
|
+
};
|
|
83
|
+
export declare function summarizeValidator(fn: ts.FunctionLikeDeclaration, o: {
|
|
84
|
+
/** the parameter whose binding is asked; undefined = master-only asked */
|
|
85
|
+
boundIdx: number | undefined;
|
|
86
|
+
/** the parameter receiving the caller's verified scope, if any */
|
|
87
|
+
identityIdx: number | undefined;
|
|
88
|
+
/** the call's arguments (object literals become constants) */
|
|
89
|
+
callArgs: readonly ts.Expression[];
|
|
90
|
+
resolve: CallResolver;
|
|
91
|
+
key: string;
|
|
92
|
+
depth: number;
|
|
93
|
+
}): ValidatorSummary;
|
|
94
|
+
/** Judge a function as a REFUSING PREDICATE (shape 2 above): parameter
|
|
95
|
+
* `identityIdx` receives the caller's verified scope, `boundIdx` the value the
|
|
96
|
+
* caller then writes. */
|
|
97
|
+
export declare function judgePredicateFunction(fn: ts.FunctionLikeDeclaration, identityIdx: number, boundIdx: number): HelperVerdict;
|
|
98
|
+
/** What a mutation handler's own body declares and refuses before `beforeLine`. */
|
|
99
|
+
export interface HandlerGuards {
|
|
100
|
+
/** Top-level `const` locals: whether bound straight to an identity read, or
|
|
101
|
+
* to `await <callee>(…)` (the callee is then judged by the caller). */
|
|
102
|
+
consts: Map<string, {
|
|
103
|
+
identityRead: boolean;
|
|
104
|
+
awaitedCallee?: string;
|
|
105
|
+
}>;
|
|
106
|
+
/** `if (!P(a, b, …)) { …throw }` statements: the predicate and its args. */
|
|
107
|
+
refusals: {
|
|
108
|
+
predicate: string;
|
|
109
|
+
args: {
|
|
110
|
+
text: string;
|
|
111
|
+
ident?: string;
|
|
112
|
+
memberBase?: string;
|
|
113
|
+
}[];
|
|
114
|
+
line: number;
|
|
115
|
+
}[];
|
|
116
|
+
}
|
|
117
|
+
/** The block body of the `handler` of `const <handlerName> = <builder>({ … })`
|
|
118
|
+
* at the top level of `sf` (arrow, function expression or method); undefined
|
|
119
|
+
* when it cannot be located. */
|
|
120
|
+
export declare function handlerBodyOf(sf: ts.SourceFile, handlerName: string): ts.Block | undefined;
|
|
121
|
+
/** Read the direct statements of handler `name` before `beforeLine`. `null`
|
|
122
|
+
* when the handler's body cannot be located. */
|
|
123
|
+
export declare function readHandlerGuards(fileName: string, source: string, handlerName: string, beforeLine: number): HandlerGuards | null;
|
|
124
|
+
/** A CONDITIONAL boundary value at a write site (`orgId: c ? a : b`): which arm
|
|
125
|
+
* reads the caller's `args`, and whether the condition is a positive
|
|
126
|
+
* `<local>.isMaster` test (the fleet carve-out, which may write what the
|
|
127
|
+
* master names). Read with the TypeScript parser on the write-site text. */
|
|
128
|
+
export interface ConditionalBoundary {
|
|
129
|
+
field: string;
|
|
130
|
+
masterBase?: string;
|
|
131
|
+
trueReadsArgs: boolean;
|
|
132
|
+
falseReadsArgs: boolean;
|
|
133
|
+
}
|
|
134
|
+
export declare function conditionalBoundaries(text: string, fields: ReadonlySet<string>): ConditionalBoundary[];
|