Skip to content

Commit a1da9bc

Browse files
committed
fix(staking): reject unrecognised OIS_PAUSED values
`asBoolean` treated any value other than "true" as false, so `OIS_PAUSED=1` or a typo like `=ture` silently removed a notice about ongoing slashing risk. Match "true"/"false" explicitly and throw otherwise, which fails the build rather than shipping a page missing the notice. Swap the file's dead eslint-disable comments for the biome equivalents; the repo has no eslint config, and biome lints changed files in full, so editing this file surfaced its pre-existing process.env usages.
1 parent e57622a commit a1da9bc

1 file changed

Lines changed: 34 additions & 10 deletions

File tree

apps/staking/src/config/server.ts

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
1-
// Disable the following rule because this file is the intended place to declare
2-
// and load all env variables.
3-
/* eslint-disable n/no-process-env */
4-
5-
// Disable the following rule because variables in this file are only loaded at
6-
// runtime and do not influence the build outputs, thus they need not be
7-
// declared to turbo for it to be able to cache build outputs correctly.
8-
/* eslint-disable turbo/no-undeclared-env-vars */
1+
// biome-ignore-all lint/style/noProcessEnv: this file is the intended place to declare and load all env variables
2+
// biome-ignore-all lint/nursery/noUndeclaredEnvVars: most variables here are only loaded at runtime and do not influence the build outputs, thus they need not be declared to turbo for it to be able to cache build outputs correctly
93

104
import "server-only";
115

@@ -38,7 +32,31 @@ const transformOr = <T>(
3832
const getOr = (key: string, defaultValue: string): string =>
3933
transform(key, (value) => value ?? defaultValue);
4034

41-
const asBoolean = (value: string): boolean => value.toLowerCase() === "true";
35+
// Declared here rather than beside `MissingEnvironmentError` at the bottom of
36+
// the file because `asBoolean` runs during module evaluation, before a class
37+
// declared further down has left its temporal dead zone.
38+
class InvalidEnvironmentError extends Error {
39+
constructor(name: string, value: string, expected: string) {
40+
super(
41+
`Invalid value for environment variable ${name}: "${value}" (expected ${expected})!`,
42+
);
43+
this.name = "InvalidEnvironmentError";
44+
}
45+
}
46+
47+
const asBoolean = (key: string, value: string): boolean => {
48+
switch (value.toLowerCase()) {
49+
case "true": {
50+
return true;
51+
}
52+
case "false": {
53+
return false;
54+
}
55+
default: {
56+
throw new InvalidEnvironmentError(key, value, `"true" or "false"`);
57+
}
58+
}
59+
};
4260

4361
/**
4462
* Indicates that this server is the live customer-facing production server.
@@ -79,10 +97,16 @@ export const PROXYCHECK_API_KEY = demandInProduction("PROXYCHECK_API_KEY");
7997
/**
8098
* Shows the persistent banner announcing that OIS rewards are paused. Enabled
8199
* by default; set `OIS_PAUSED=false` to remove the banner when rewards resume.
100+
* Anything other than `true` / `false` throws rather than defaulting, so a typo
101+
* can't silently drop a notice about ongoing slashing risk.
82102
* `/` is statically prerendered, so this is baked in at build time -- flipping
83103
* it needs a redeploy, not just an env var change.
84104
*/
85-
export const OIS_PAUSED = transformOr("OIS_PAUSED", asBoolean, true);
105+
export const OIS_PAUSED = transformOr(
106+
"OIS_PAUSED",
107+
(value) => asBoolean("OIS_PAUSED", value),
108+
true,
109+
);
86110
// This needs to be a public key that has SOL in it all the time, it will be used as a payer in the transaction simulation to compute the claimable rewards
87111
// such simulation fails when the payer has no funds.
88112
export const SIMULATION_PAYER_ADDRESS = getOr(

0 commit comments

Comments
 (0)