@@ -4,119 +4,89 @@ import { Schema } from "effect";
44
55const authSecret = Schema . String . check ( Schema . isMinLength ( 32 ) ) ;
66
7- const parseUrl = ( value : string ) => {
8- try {
9- return new URL ( value ) ;
10- } catch {
11- return undefined ;
12- }
13- } ;
14- const safeUrl = ( value : string , isDev : boolean , originOnly : boolean ) => {
15- const url = parseUrl ( value ) ;
16- if ( ! url || url . username || url . password || url . search || url . hash ) return false ;
17- if ( originOnly && url . pathname !== "/" ) return false ;
18- if ( url . protocol === "https:" ) return true ;
19- return (
20- isDev &&
21- url . protocol === "http:" &&
22- ( url . hostname === "localhost" || url . hostname === "127.0.0.1" || url . hostname === "[::1]" )
23- ) ;
24- } ;
25- const authUrl = ( isDev : boolean ) =>
26- Schema . NonEmptyString . check (
27- Schema . makeFilter (
28- ( value ) => safeUrl ( value , isDev , true ) || "expected a canonical HTTPS origin" ,
29- ) ,
30- ) ;
31- const oidcIssuer = ( isDev : boolean ) =>
32- Schema . NonEmptyString . check (
33- Schema . makeFilter (
34- ( value ) => safeUrl ( value , isDev , false ) || "expected a canonical HTTPS issuer" ,
35- ) ,
36- ) ;
37-
38- export const authUrlSchema = ( isBuilding : boolean , isDev : boolean ) => {
39- const schema = authUrl ( isDev ) ;
40- return ( isBuilding ? Schema . optional ( schema ) : schema ) as typeof schema ;
41- } ;
7+ const safeUrl = Schema . NonEmptyString . check (
8+ Schema . makeFilter ( ( value ) => {
9+ if ( ! URL . canParse ( value ) ) return false ;
4210
43- export const oidcIssuerSchema = ( isBuilding : boolean , isDev : boolean ) => {
44- const schema = oidcIssuer ( isDev ) ;
45- return ( isBuilding ? Schema . optional ( schema ) : schema ) as typeof schema ;
46- } ;
11+ const url = new URL ( value ) ;
12+ if ( url . username || url . password || url . search || url . hash ) return false ;
13+ if ( url . protocol === "https:" ) return true ;
14+ return (
15+ dev &&
16+ url . protocol === "http:" &&
17+ ( url . hostname === "localhost" || url . hostname === "127.0.0.1" || url . hostname === "[::1]" )
18+ ) ;
19+ } ) ,
20+ ) ;
21+ const authUrl = safeUrl . check (
22+ Schema . makeFilter (
23+ ( value ) => URL . parse ( value ) ?. pathname === "/" || "expected a canonical HTTPS origin" ,
24+ ) ,
25+ ) ;
4726
48- export const mcpResourceSchema = ( isBuilding : boolean , isDev : boolean ) => {
49- const schema = authUrl ( isDev ) ;
50- return ( isBuilding ? Schema . optional ( schema ) : schema ) as typeof schema ;
51- } ;
27+ export const authUrlSchema = building ? Schema . optional ( authUrl ) : authUrl ;
28+ export const oidcIssuerSchema = building ? Schema . optional ( safeUrl ) : safeUrl ;
29+ export const mcpResourceSchema = building ? Schema . optional ( authUrl ) : authUrl ;
5230
5331export const variables = defineEnvVars ( {
5432 BETTER_AUTH_SECRET : {
5533 public : false ,
5634 static : false ,
5735 description : "Secret used to sign and encrypt Grove authentication state." ,
58- schema : Schema . toStandardSchemaV1 (
59- ( building ? Schema . optional ( authSecret ) : authSecret ) as typeof authSecret ,
60- ) ,
36+ schema : Schema . toStandardSchemaV1 ( building ? Schema . optional ( authSecret ) : authSecret ) ,
6137 } ,
6238 BETTER_AUTH_URL : {
6339 public : false ,
6440 static : false ,
6541 description : "Canonical public URL used for Grove authentication callbacks." ,
66- schema : Schema . toStandardSchemaV1 ( authUrlSchema ( building , dev ) ) ,
42+ schema : Schema . toStandardSchemaV1 ( authUrlSchema ) ,
6743 } ,
6844 DATABASE_URL : {
6945 public : false ,
7046 static : false ,
7147 description : "PostgreSQL connection URL for Grove's durable state." ,
7248 schema : Schema . toStandardSchemaV1 (
73- ( building
74- ? Schema . optional ( Schema . NonEmptyString )
75- : Schema . NonEmptyString ) as typeof Schema . NonEmptyString ,
49+ building ? Schema . optional ( Schema . NonEmptyString ) : Schema . NonEmptyString ,
7650 ) ,
7751 } ,
7852 GROVE_OIDC_CLIENT_ID : {
7953 public : false ,
8054 static : false ,
8155 description : "OIDC client ID used only for Grove browser login." ,
8256 schema : Schema . toStandardSchemaV1 (
83- ( building
84- ? Schema . optional ( Schema . NonEmptyString )
85- : Schema . NonEmptyString ) as typeof Schema . NonEmptyString ,
57+ building ? Schema . optional ( Schema . NonEmptyString ) : Schema . NonEmptyString ,
8658 ) ,
8759 } ,
8860 GROVE_OIDC_CLIENT_SECRET : {
8961 public : false ,
9062 static : false ,
9163 description : "OIDC client secret used only for Grove browser login." ,
9264 schema : Schema . toStandardSchemaV1 (
93- ( building
94- ? Schema . optional ( Schema . NonEmptyString )
95- : Schema . NonEmptyString ) as typeof Schema . NonEmptyString ,
65+ building ? Schema . optional ( Schema . NonEmptyString ) : Schema . NonEmptyString ,
9666 ) ,
9767 } ,
9868 GROVE_OIDC_ISSUER : {
9969 public : false ,
10070 static : false ,
10171 description : "Pinned OIDC issuer used for Grove browser login and discovery." ,
102- schema : Schema . toStandardSchemaV1 ( oidcIssuerSchema ( building , dev ) ) ,
72+ schema : Schema . toStandardSchemaV1 ( oidcIssuerSchema ) ,
10373 } ,
10474 GROVE_MCP_ISSUER : {
10575 public : false ,
10676 static : false ,
10777 description : "Pinned authorization-server issuer for MCP bearer tokens." ,
108- schema : Schema . toStandardSchemaV1 ( oidcIssuerSchema ( building , dev ) ) ,
78+ schema : Schema . toStandardSchemaV1 ( oidcIssuerSchema ) ,
10979 } ,
11080 GROVE_MCP_JWKS_URL : {
11181 public : false ,
11282 static : false ,
11383 description : "JWKS endpoint for validating MCP bearer tokens." ,
114- schema : Schema . toStandardSchemaV1 ( oidcIssuerSchema ( building , dev ) ) ,
84+ schema : Schema . toStandardSchemaV1 ( oidcIssuerSchema ) ,
11585 } ,
11686 GROVE_MCP_RESOURCE : {
11787 public : false ,
11888 static : false ,
11989 description : "Canonical origin of Grove's MCP protected resource." ,
120- schema : Schema . toStandardSchemaV1 ( mcpResourceSchema ( building , dev ) ) ,
90+ schema : Schema . toStandardSchemaV1 ( mcpResourceSchema ) ,
12191 } ,
12292} ) ;
0 commit comments