Skip to content

Commit

Permalink
chore: add protected trpc router example (t3-oss#194)
Browse files Browse the repository at this point in the history
  • Loading branch information
bhatvikrant authored Jul 22, 2022
1 parent 0b4d7fc commit aef8ef4
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 30 deletions.
27 changes: 21 additions & 6 deletions src/installers/trpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,6 @@ export const trpcInstaller: Installer = async ({
const contextSrc = path.join(trpcAssetDir, contextFile);
const contextDest = path.join(projectDir, "src/server/router/context.ts");

if (usingAuth) {
const authRouterSrc = path.join(trpcAssetDir, "auth-router.ts");
const authRouterDest = path.join(projectDir, "src/server/router/auth.ts");
await fs.copy(authRouterSrc, authRouterDest);
}

const indexRouterFile = usingAuth
? "auth-index-router.ts"
: "index-router.ts";
Expand All @@ -61,11 +55,32 @@ export const trpcInstaller: Installer = async ({
"src/server/router/example.ts",
);

const protectedExampleRouterSrc = path.join(
trpcAssetDir,
"protected-example-router.ts",
);
const protectedExampleRouterDest = path.join(
projectDir,
"src/server/router/protected-example-router.ts",
);

const protectedRouterSrc = path.join(trpcAssetDir, "protected-router.ts");
const protectedRouterDest = path.join(
projectDir,
"src/server/router/protected-router.ts",
);

await Promise.all([
fs.copy(apiHandlerSrc, apiHandlerDest),
fs.copy(utilsSrc, utilsDest),
fs.copy(contextSrc, contextDest),
fs.copy(indexRouterSrc, indexRouterDest),
fs.copy(exampleRouterSrc, exampleRouterDest),
...(usingAuth
? [
fs.copy(protectedExampleRouterSrc, protectedExampleRouterDest),
fs.copy(protectedRouterSrc, protectedRouterDest),
]
: []),
]);
};
4 changes: 2 additions & 2 deletions template/addons/trpc/auth-index-router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { createRouter } from "./context";
import superjson from "superjson";

import { exampleRouter } from "./example";
import { authRouter } from "./auth";
import { protectedExampleRouter } from "./protected-example-router";

export const appRouter = createRouter()
.transformer(superjson)
.merge("example.", exampleRouter)
.merge("auth.", authRouter);
.merge("question.", protectedExampleRouter);

// export type definition of API
export type AppRouter = typeof appRouter;
22 changes: 0 additions & 22 deletions template/addons/trpc/auth-router.ts

This file was deleted.

14 changes: 14 additions & 0 deletions template/addons/trpc/protected-example-router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { createProtectedRouter } from "./protected-router";

// Example router with queries that can only be hit if the user requesting is signed in
export const protectedExampleRouter = createProtectedRouter()
.query("getSession", {
resolve({ ctx }) {
return ctx.session;
},
})
.query("getSecretMessage", {
resolve({ ctx }) {
return "He who asks a question is a fool for five minutes; he who does not ask a question remains a fool forever.";
},
});
20 changes: 20 additions & 0 deletions template/addons/trpc/protected-router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as trpc from "@trpc/server";
import { createRouter } from "./context";

/**
* Creates a tRPC router that asserts all queries and mutations are from an authorized user. Will throw an unauthorized error if a user is not signed in.
*/
export function createProtectedRouter() {
return createRouter().middleware(({ ctx, next }) => {
if (!ctx.session || !ctx.session.user) {
throw new trpc.TRPCError({ code: "UNAUTHORIZED" });
}
return next({
ctx: {
...ctx,
// infers that `session` is non-nullable to downstream resolvers
session: { ...ctx.session, user: ctx.session.user },
},
});
});
}

0 comments on commit aef8ef4

Please sign in to comment.