Skip to content

Commit 943e601

Browse files
committed
Code comments/formatting
1 parent 91b6504 commit 943e601

2 files changed

Lines changed: 40 additions & 13 deletions

File tree

apps/webapp/app/env.server.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1455,9 +1455,7 @@ const EnvironmentSchema = z
14551455
PRIVATE_CONNECTIONS_ENABLED: z.string().optional(),
14561456
PRIVATE_CONNECTIONS_AWS_ACCOUNT_IDS: z.string().optional(),
14571457

1458-
// Force the RBAC plugin loader to use the OSS fallback, bypassing the enterprise plugin.
1459-
// Set to "1"/"true" in tests so auth behavior is deterministic regardless of whether
1460-
// @triggerdotdev/plugins/rbac is installed in the environment.
1458+
// Force RBAC to not use the plugin
14611459
RBAC_FORCE_FALLBACK: BoolEnv.default(false),
14621460
})
14631461
.and(GithubAppEnvSchema)

internal-packages/rbac/src/index.ts

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ export type { RoleBaseAccessController, RbacAbility, RbacResource } from "@trigg
1515
type RbacHelpers = { getSessionUserId: (request: Request) => Promise<string | null> };
1616

1717
export type RbacCreateOptions = {
18-
// When true, skip loading the enterprise plugin and use the OSS fallback directly.
19-
// Useful for tests that need deterministic auth behavior without the enterprise plugin.
18+
// When true, skip loading the plugin, useful for tests
2019
forceFallback?: boolean;
2120
};
2221

@@ -25,9 +24,7 @@ export type RbacCreateOptions = {
2524
// a route with action: "trigger" because "write:tasks" was listed in the route's
2625
// superScopes array. The new ability model matches scope-action strictly, so we
2726
// restore the prior semantic here: when the underlying ability denies for action
28-
// X, retry with each aliased action. The retry covers both OSS fallback
29-
// (scope-based buildJwtAbility) and enterprise (DB/CASL-based) paths
30-
// transparently — neither implementation needs to know about aliases.
27+
// X, retry with each aliased action.
3128
const ACTION_ALIASES: Record<string, readonly string[]> = {
3229
trigger: ["write"],
3330
batchTrigger: ["write"],
@@ -45,7 +42,7 @@ export function withActionAliases(underlying: RbacAbility): RbacAbility {
4542
};
4643
}
4744

48-
// Loads the enterprise plugin lazily; falls back to the OSS implementation if not installed.
45+
// Loads the plugin lazily; falls back to the fallback implementation if not installed.
4946
// Synchronous create() avoids top-level await (not supported in the webapp's CJS build).
5047
class LazyController implements RoleBaseAccessController {
5148
private readonly _init: Promise<RoleBaseAccessController>;
@@ -66,8 +63,34 @@ class LazyController implements RoleBaseAccessController {
6663
const moduleName = "@triggerdotdev/plugins/rbac";
6764
const module = await import(moduleName);
6865
const plugin: RoleBasedAccessControlPlugin = module.default;
66+
console.log("RBAC: using enterprise plugin implementation");
6967
return plugin.create(helpers);
70-
} catch {
68+
} catch (err) {
69+
// The dynamic import either succeeded (enterprise tier) or failed
70+
// for one of two distinct reasons. Distinguishing them is critical
71+
// for debugging — silently swallowing the error here is what
72+
// produced "why is the fallback being used?" mysteries before.
73+
//
74+
// 1. Module-not-found — expected for OSS deployments where the
75+
// cloud plugin isn't installed. Logged at info level only when
76+
// RBAC_LOG_FALLBACK=1 so production OSS logs stay quiet.
77+
// 2. Anything else (transitive dep missing, init error, syntax
78+
// error in the plugin's dist, etc.) — a real bug. Always
79+
// logged loudly so it surfaces in CI / production logs.
80+
const code = (err as NodeJS.ErrnoException | undefined)?.code;
81+
const isModuleNotFound = code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND";
82+
if (!isModuleNotFound) {
83+
console.error(
84+
"RBAC: enterprise plugin found but failed to load; falling back to OSS implementation",
85+
err
86+
);
87+
} else if (process.env.RBAC_LOG_FALLBACK === "1") {
88+
console.log(
89+
"RBAC: enterprise plugin not installed (ERR_MODULE_NOT_FOUND); using OSS fallback"
90+
);
91+
} else {
92+
console.log(`RBAC: using fallback implementation. ${err}`);
93+
}
7194
return new RoleBaseAccessFallback(prisma).create(helpers);
7295
}
7396
}
@@ -115,7 +138,9 @@ class LazyController implements RoleBaseAccessController {
115138
return auth;
116139
}
117140

118-
async allPermissions(...args: Parameters<RoleBaseAccessController["allPermissions"]>): Promise<Permission[]> {
141+
async allPermissions(
142+
...args: Parameters<RoleBaseAccessController["allPermissions"]>
143+
): Promise<Permission[]> {
119144
return (await this.c()).allPermissions(...args);
120145
}
121146

@@ -141,7 +166,9 @@ class LazyController implements RoleBaseAccessController {
141166
return (await this.c()).deleteRole(...args);
142167
}
143168

144-
async getUserRole(...args: Parameters<RoleBaseAccessController["getUserRole"]>): Promise<Role | null> {
169+
async getUserRole(
170+
...args: Parameters<RoleBaseAccessController["getUserRole"]>
171+
): Promise<Role | null> {
145172
return (await this.c()).getUserRole(...args);
146173
}
147174

@@ -157,7 +184,9 @@ class LazyController implements RoleBaseAccessController {
157184
return (await this.c()).removeUserRole(...args);
158185
}
159186

160-
async getTokenRole(...args: Parameters<RoleBaseAccessController["getTokenRole"]>): Promise<Role | null> {
187+
async getTokenRole(
188+
...args: Parameters<RoleBaseAccessController["getTokenRole"]>
189+
): Promise<Role | null> {
161190
return (await this.c()).getTokenRole(...args);
162191
}
163192

0 commit comments

Comments
 (0)