Xaohs
Xaohs
Explore posts from servers
TTCTheo's Typesafe Cult
Created by Xaohs on 2/15/2024 in #questions
App directory fetch data from endpoint with query parameters
Hi there! Yeah I see that the server component itself includes those params as props, so that works. I guess this would be the pattern to follow then
4 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 11/16/2023 in #questions
What's a good way to "protect" a public TRPC endpoint
Yeah we have a extra strict rate limit on that api endpoint in specific and our budget is setup in a good way.
35 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 11/16/2023 in #questions
What's a good way to "protect" a public TRPC endpoint
Which isn't an option in this case for us
35 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 11/16/2023 in #questions
What's a good way to "protect" a public TRPC endpoint
Yeah, it honestly sounds like the only actual good solution is putting it behind an auth wall
35 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 11/16/2023 in #questions
What's a good way to "protect" a public TRPC endpoint
Our google maps endpoint is limited to a certain budget anyway, so if an abuser would attempt, they wouldn't get that far they'd only waste us a few dollars. Been running for more than a month now and no abuse has happened yet, but this could easily change.
35 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 11/16/2023 in #questions
What's a good way to "protect" a public TRPC endpoint
Damn y'all came back to this huh. So the system that's currently in place for me is. I have an API endpoint setup that when called does some preliminary checks of checking the referer, the origin, user agent. This then generates a short lived 5 minute signed token and returns it. On the frontend side of things, this token is then saved. Everytime the expiry time comes close a new one is generated for the user. On the API endpoint in question (google maps in this case) I do a check if this token is correct and not expired, and if it's correct I let the request through. This is still open for abuse, an abuser could easily throw a request to my token endpoint, get a token, use that token to then make a new request to my google map endpoint for 5 minutes before fetching the other API endpoint for a new token again. Of course the abuser would have to know a token is required, which i'm not sure how they will find out as I don't leak any info, but yeah I am still unsure how other people do this without auth, as it's essential that this API remains public. Making people login with OAuth instantly fixes this issue of course. @erik.gh @Deveroonie , if you have any further insights i'd love to know.
35 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 11/16/2023 in #questions
What's a good way to "protect" a public TRPC endpoint
I guess technically people would still be able to just call my token creation procedure, get the token created, and use that token in the API calls.. but at least this is another layer.. not really sure what else I can do
35 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 11/16/2023 in #questions
What's a good way to "protect" a public TRPC endpoint
I've implemented a token authentication system to ensure that only legitimate frontend requests can access certain API endpoints. These are some of the things i've done: 1. useToken Hook: In _app.tsx, I've set up a useToken hook. This hook keeps a short-lived token in localStorage. The token is generated by calling an API endpoint that creates a JWT (JSON Web Token) with an expiration time of 30 minutes. 2. TRPC Configuration: In the TRPC client configuration, I've set the request header x-token to the token stored in localStorage. 3. Middleware for Token Validation: On the server side, I've created a middleware in TRPC that validates the x-token header in each request. It checks if the provided token is a valid JWT using jsonwebtoken's validate function:
export const verifyToken = (token: string): boolean => {
try {
verify(token, someSecret);
return true;
} catch (error) {
return false;
}
};

const validateTokenMiddleware = t.middleware(({ next, ctx }) => {
const token = ctx.req?.headers['x-token'];
if (typeof token === 'string') {
const isValid = verifyToken(token);
if (isValid) {
return next({
...
});
}
}
throw new TRPCError({ code: 'UNAUTHORIZED' });
});

export const verifyToken = (token: string): boolean => {
try {
verify(token, someSecret);
return true;
} catch (error) {
return false;
}
};

const validateTokenMiddleware = t.middleware(({ next, ctx }) => {
const token = ctx.req?.headers['x-token'];
if (typeof token === 'string') {
const isValid = verifyToken(token);
if (isValid) {
return next({
...
});
}
}
throw new TRPCError({ code: 'UNAUTHORIZED' });
});

I believe this setup effectively secures my API endpoints by validating that users are indeed coming from my frontend. However, I'd love some suggestions or input on this setup. If you have any ideas or feedback, I'd love to hear them! Thanks! 🙌
35 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 11/16/2023 in #questions
What's a good way to "protect" a public TRPC endpoint
Hmm, yeah I think that might be a good option
35 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 11/16/2023 in #questions
What's a good way to "protect" a public TRPC endpoint
Do you mean, i'd create a short-lived token for each user visiting the website, which is stored in my DB, and whenever a user requests the API endpoint that would call the Google Maps API I check if this user has a correct token (and is indeed from my frontend code) ?
35 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 11/16/2023 in #questions
What's a good way to "protect" a public TRPC endpoint
Yes JWT's would work, but this API endpoint is meant for all users, not just authenticated users, so long as they're from my frontend code and not just calling it via crud/postman etc.
35 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 11/16/2023 in #questions
What's a good way to "protect" a public TRPC endpoint
As in, the trpc route that calls the Google Maps endpoint would still be vulnerable as an API key shared through the frontend isn't secure at all and people could easily get that api key and construct calls to my trpc endpoint which then calls Google maps, my goal is to avoid people outside my application constructing these requests essentially making use of the maps endpoint through my app. Rate limiting will help, but it won't stop this behaviour completely.
35 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 11/16/2023 in #questions
What's a good way to "protect" a public TRPC endpoint
Yeah but from the frontend that would not make much sense, no? I'd be using the key to the API in my frontend that will eventually call the maps api
35 replies
TTCTheo's Typesafe Cult
Created by iboughtbed on 10/29/2023 in #questions
Best React (Next.js) PDF libraries?
If you only need to view pdfs I'd use an iframe. Otherwise if you need to actually make the pdfs as well, I'm a big fan of react-pdf for that.
6 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 10/17/2023 in #questions
Render either a Sheet, or a Dialog in a streamlined way with Shadcn/ui?
Well, I think sheets are just a way better experience on mobile than dialogs, dialogs feel very intrusive, and don't look as nice on mobile as sheets do.
18 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 10/17/2023 in #questions
Render either a Sheet, or a Dialog in a streamlined way with Shadcn/ui?
Hmm yeah. I appreciate your opinion on this! Not sure if this is kind of an anti-pattern I'm developing but we'll see haha
18 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 10/17/2023 in #questions
Render either a Sheet, or a Dialog in a streamlined way with Shadcn/ui?
Yeah that could also work, but that kind of disables all kind of props that I'd like to pass to the components from time to time
18 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 10/17/2023 in #questions
Render either a Sheet, or a Dialog in a streamlined way with Shadcn/ui?
I've did some brainstorming and came up with something like this, which I think is pretty okay(ish):
function useMode() {
const { windowSize } = useWindowSize();
return windowSize.lg ? 'dialog' : 'sheet';
}

type DialogOrSheetProps = DialogAndSheetPrimitive.DialogProps;
const DialogOrSheet: FC<DialogOrSheetProps> = ({ ...props }) => {
const mode = useMode();
if (mode === 'dialog') {
return <Dialog.Dialog {...props} />;
} else {
return <Sheet.Sheet {...props} />;
}
};

type DialogOrSheetTriggerProps = DialogAndSheetPrimitive.DialogTriggerProps;
const DialogOrSheetTrigger: FC<DialogOrSheetTriggerProps> = ({ ...props }) => {
const mode = useMode();
if (mode === 'dialog') {
return <Dialog.DialogTrigger {...props} />;
} else {
return <Sheet.SheetTrigger {...props} />;
}
};

.......
function useMode() {
const { windowSize } = useWindowSize();
return windowSize.lg ? 'dialog' : 'sheet';
}

type DialogOrSheetProps = DialogAndSheetPrimitive.DialogProps;
const DialogOrSheet: FC<DialogOrSheetProps> = ({ ...props }) => {
const mode = useMode();
if (mode === 'dialog') {
return <Dialog.Dialog {...props} />;
} else {
return <Sheet.Sheet {...props} />;
}
};

type DialogOrSheetTriggerProps = DialogAndSheetPrimitive.DialogTriggerProps;
const DialogOrSheetTrigger: FC<DialogOrSheetTriggerProps> = ({ ...props }) => {
const mode = useMode();
if (mode === 'dialog') {
return <Dialog.DialogTrigger {...props} />;
} else {
return <Sheet.SheetTrigger {...props} />;
}
};

.......
18 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 10/17/2023 in #questions
Render either a Sheet, or a Dialog in a streamlined way with Shadcn/ui?
Yeah, of course that would work, but that's not scalable for long-term in my opinion. You'd have so much repeated code for in essence, the exact same thing just a slightly different type of popup
18 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 9/30/2023 in #questions
Image Memory Leak in NextJS?
Update, some more testing has been done. It seems the RAM is kept hostage up until it is actually needed by other processes, For example, let's say the baseline for a project is 200mb memory usage, and after loading in a bunch of images, you're at 800mb, and your system hits it's peak memory usage, whenever other processes actually need this memory it seems the 800mb slowly gets lowered back up to the baseline (if needed) to keep memory usage under ~95%. I'm not sure if this is how it's supposed to work, but that's what I can see on my end I'd love for somebody to provide their opinions on this.
3 replies