From ae8b8796553355044f097f7bd99ad17d6b4e1edf Mon Sep 17 00:00:00 2001 From: LekoArts Date: Wed, 1 Nov 2023 14:20:17 +0100 Subject: [PATCH 1/3] fix(*): Use isTruthy helper --- packages/nextjs/src/server/constants.ts | 3 ++- .../src/utils/mergeNextClerkPropsWithEnv.ts | 5 ++-- packages/remix/src/ssr/authenticateRequest.ts | 7 ++++-- packages/sdk-node/src/utils.ts | 4 ++-- packages/shared/src/underscore.ts | 24 +++++++++++++++++++ 5 files changed, 36 insertions(+), 7 deletions(-) diff --git a/packages/nextjs/src/server/constants.ts b/packages/nextjs/src/server/constants.ts index 03d39b73d18..4c232899d80 100644 --- a/packages/nextjs/src/server/constants.ts +++ b/packages/nextjs/src/server/constants.ts @@ -1,4 +1,5 @@ import { deprecated } from '@clerk/shared/deprecated'; +import { isTruthy } from '@clerk/shared/underscore'; /** * @deprecated Use `CLERK_JS_VERSION` instead. @@ -29,6 +30,6 @@ if (FRONTEND_API) { export const PUBLISHABLE_KEY = process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY || ''; export const DOMAIN = process.env.NEXT_PUBLIC_CLERK_DOMAIN || ''; export const PROXY_URL = process.env.NEXT_PUBLIC_CLERK_PROXY_URL || ''; -export const IS_SATELLITE = process.env.NEXT_PUBLIC_CLERK_IS_SATELLITE === 'true' || false; +export const IS_SATELLITE = isTruthy(process.env.NEXT_PUBLIC_CLERK_IS_SATELLITE) || false; export const SIGN_IN_URL = process.env.NEXT_PUBLIC_CLERK_SIGN_IN_URL || ''; export const SIGN_UP_URL = process.env.NEXT_PUBLIC_CLERK_SIGN_UP_URL || ''; diff --git a/packages/nextjs/src/utils/mergeNextClerkPropsWithEnv.ts b/packages/nextjs/src/utils/mergeNextClerkPropsWithEnv.ts index 5bd60fe814e..292da5e0fe5 100644 --- a/packages/nextjs/src/utils/mergeNextClerkPropsWithEnv.ts +++ b/packages/nextjs/src/utils/mergeNextClerkPropsWithEnv.ts @@ -1,4 +1,5 @@ -/* eslint-disable turbo/no-undeclared-env-vars */ +import { isTruthy } from '@clerk/shared/underscore'; + import type { NextClerkProviderProps } from '../types'; export const mergeNextClerkPropsWithEnv = (props: Omit) => { @@ -10,7 +11,7 @@ export const mergeNextClerkPropsWithEnv = (props: Omit { domain: process.env.CLERK_DOMAIN || '', proxyUrl: process.env.CLERK_PROXY_URL || '', signInUrl: process.env.CLERK_SIGN_IN_URL || '', - isSatellite: process.env.CLERK_IS_SATELLITE === 'true', + isSatellite: isTruthy(process.env.CLERK_IS_SATELLITE), jwtKey: process.env.CLERK_JWT_KEY || '', }; }; diff --git a/packages/shared/src/underscore.ts b/packages/shared/src/underscore.ts index 76a0adca0f1..7268b77fb2e 100644 --- a/packages/shared/src/underscore.ts +++ b/packages/shared/src/underscore.ts @@ -82,3 +82,27 @@ export const deepCamelToSnake = createDeepObjectTransformer(camelToSnake); * camelCased keys are removed. */ export const deepSnakeToCamel = createDeepObjectTransformer(snakeToCamel); + +/** + * Returns true for `true`, true, positive numbers. + * Returns false for `false`, false, 0, negative integers and anything else. + */ +export function isTruthy(value: any): boolean { + // Return if Boolean + if (typeof value === `boolean`) return value; + + // Return false if null or undefined + if (value === undefined || value === null) return false; + + // If the String is true or false + if (value.toLowerCase() === `true`) return true; + if (value.toLowerCase() === `false`) return false; + + // Now check if it's a number + const number = parseInt(value, 10); + if (isNaN(number)) return false; + if (number > 0) return true; + + // Default to false + return false; +} From 728e422e3babb458edb180f56fdf80e05644977b Mon Sep 17 00:00:00 2001 From: Lennart Date: Wed, 1 Nov 2023 14:23:07 +0100 Subject: [PATCH 2/3] Create fifty-rats-rhyme.md --- .changeset/fifty-rats-rhyme.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .changeset/fifty-rats-rhyme.md diff --git a/.changeset/fifty-rats-rhyme.md b/.changeset/fifty-rats-rhyme.md new file mode 100644 index 00000000000..595b7b6cbf9 --- /dev/null +++ b/.changeset/fifty-rats-rhyme.md @@ -0,0 +1,8 @@ +--- +"@clerk/nextjs": patch +"@clerk/remix": patch +"@clerk/clerk-sdk-node": patch +"@clerk/shared": patch +--- + +Introduce `isTruthy` helper to better cast environment variables to a boolean. Previously only the string `"true"` was checked, now `true`, `"true"`, `"1"`, and `1` will work. From 809cbb77aca2c742c7b43448ae55785455065465 Mon Sep 17 00:00:00 2001 From: LekoArts Date: Wed, 1 Nov 2023 14:39:33 +0100 Subject: [PATCH 3/3] chore(shared): Add test --- .../shared/src/__tests__/underscore.test.ts | 28 ++++++++++++++++++- packages/shared/src/underscore.ts | 10 ++++--- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/packages/shared/src/__tests__/underscore.test.ts b/packages/shared/src/__tests__/underscore.test.ts index 2398cf84d37..2a86c56a4cd 100644 --- a/packages/shared/src/__tests__/underscore.test.ts +++ b/packages/shared/src/__tests__/underscore.test.ts @@ -1,4 +1,4 @@ -import { deepCamelToSnake, deepSnakeToCamel, isIPV4Address, titleize, toSentence } from '../underscore'; +import { deepCamelToSnake, deepSnakeToCamel, isIPV4Address, isTruthy, titleize, toSentence } from '../underscore'; describe('toSentence', () => { it('returns a single item as-is', () => { @@ -178,3 +178,29 @@ describe('camelToSnakeKeys', () => { expect(anotherSampleObject).not.toHaveProperty('oneKey'); }); }); + +describe(`isTruthy`, () => { + it(`handles booleans`, () => { + expect(isTruthy(true)).toBe(true); + expect(isTruthy(false)).toBe(false); + }); + it(`handles true or false strings `, () => { + expect(isTruthy(`true`)).toBe(true); + expect(isTruthy(`false`)).toBe(false); + expect(isTruthy(`TRUE`)).toBe(true); + expect(isTruthy(`FALSE`)).toBe(false); + expect(isTruthy(`TruE`)).toBe(true); + expect(isTruthy(`FalsE`)).toBe(false); + }); + it(`handles numbers`, () => { + expect(isTruthy(`1`)).toBe(true); + expect(isTruthy(`0`)).toBe(false); + expect(isTruthy(`-1`)).toBe(false); + expect(isTruthy(1)).toBe(true); + expect(isTruthy(0)).toBe(false); + expect(isTruthy(-1)).toBe(false); + }); + it(`defaults to false`, () => { + expect(isTruthy(`foobar`)).toBe(false); + }); +}); diff --git a/packages/shared/src/underscore.ts b/packages/shared/src/underscore.ts index 7268b77fb2e..7558c17b91d 100644 --- a/packages/shared/src/underscore.ts +++ b/packages/shared/src/underscore.ts @@ -87,7 +87,7 @@ export const deepSnakeToCamel = createDeepObjectTransformer(snakeToCamel); * Returns true for `true`, true, positive numbers. * Returns false for `false`, false, 0, negative integers and anything else. */ -export function isTruthy(value: any): boolean { +export function isTruthy(value: unknown): boolean { // Return if Boolean if (typeof value === `boolean`) return value; @@ -95,11 +95,13 @@ export function isTruthy(value: any): boolean { if (value === undefined || value === null) return false; // If the String is true or false - if (value.toLowerCase() === `true`) return true; - if (value.toLowerCase() === `false`) return false; + if (typeof value === `string`) { + if (value.toLowerCase() === `true`) return true; + if (value.toLowerCase() === `false`) return false; + } // Now check if it's a number - const number = parseInt(value, 10); + const number = parseInt(value as string, 10); if (isNaN(number)) return false; if (number > 0) return true;