Skip to content

Commit

Permalink
Merge branch 'fix/user-scenarios-not-being-generated' of github.com:d…
Browse files Browse the repository at this point in the history
…ac09/redwood into fix/user-scenarios-not-being-generated

* 'fix/user-scenarios-not-being-generated' of github.com:dac09/redwood:
  Amend import order in auth templates according to ESLint rules introduced in v2.0 (redwoodjs#6059)
  docs(tutorial): Adds more TS hints in the toturial (redwoodjs#6115)
  Revert auth provider refactor (redwoodjs#6135)
  • Loading branch information
dac09 committed Aug 9, 2022
2 parents c0c2684 + 2a472aa commit 1af2578
Show file tree
Hide file tree
Showing 32 changed files with 637 additions and 947 deletions.
18 changes: 18 additions & 0 deletions docs/docs/tutorial/chapter2/cells.md
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,24 @@ export const Success = ({ posts }: CellSuccessProps<ArticlesQuery>) => {
</TabItem>
</Tabs>

<ShowForTs>

:::tip Using generated types

At this point, you might see an error in your Cell while trying to import from `types/graphql`: "The type ArticlesQuery does not exist"

When you have the dev server (via `yarn rw dev`) running, the CLI watches files for changes and triggers type generation automatically, but you can trigger it manually too by running:

```bash
yarn rw g types
```

This looks at your Cell's `QUERY` and—as long as it's valid—tries to automatically create a TypeScript type for you to use in your code.

:::

</ShowForTs>

Let's plug this cell into our `HomePage` and see what happens:

<Tabs groupId="js-ts">
Expand Down
60 changes: 60 additions & 0 deletions docs/docs/tutorial/chapter7/rbac.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,66 @@ export const getCurrentUser = async (session) => {
</TabItem>
</Tabs>
<ShowForTs>
### Fixing the hasRole function
At this point, you might notice an error in your `api/src/lib/auth.ts` file, in the `hasRole` function. TypeScript is trying to help you here, by highlighting that roles can never be an array of strings:
```ts title="api/src/lib/auth.ts"
export const hasRole = (roles: AllowedRoles): boolean => {

// ...

} else if (Array.isArray(currentUserRoles)) {
// 👇 TypeScript will now be telling you 'some' doesn't exist on type never:
// highlight-next-line
return currentUserRoles?.some((allowedRole) => roles === allowedRole)
}
}
```
This is because we now know that the type of `currentUser.roles` is a `string` based on the type being returned from Prisma. So you can safely remove the block of code where it's checking if roles is an array:
```diff title="api/src/lib/auth.ts"
export const hasRole = (roles: AllowedRoles): boolean => {
if (!isAuthenticated()) {
return false
}

const currentUserRoles = context.currentUser?.roles

if (typeof roles === 'string') {
if (typeof currentUserRoles === 'string') {
// roles to check is a string, currentUser.roles is a string
return currentUserRoles === roles
- } else if (Array.isArray(currentUserRoles)) {
- // roles to check is a string, currentUser.roles is an array
- return currentUserRoles?.some((allowedRole) => roles === allowedRole)
}
}

if (Array.isArray(roles)) {
if (Array.isArray(currentUserRoles)) {
// roles to check is an array, currentUser.roles is an array
return currentUserRoles?.some((allowedRole) =>
roles.includes(allowedRole)
)
} else if (typeof context?.currentUser?.roles === 'string') {
// roles to check is an array, currentUser.roles is a string
return roles.some(
(allowedRole) => context.currentUser?.roles === allowedRole
)
}
}

// roles not found
return false
}
```
</ShowForTs>
### Restricting Access via Routes
The easiest way to prevent access to an entire URL is via the Router. The `<Private>` component takes a prop `roles` in which you can give a list of only those role(s) that should have access:
Expand Down
18 changes: 18 additions & 0 deletions docs/versioned_docs/version-2.2/tutorial/chapter2/cells.md
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,24 @@ export const Success = ({ posts }: CellSuccessProps<ArticlesQuery>) => {
</TabItem>
</Tabs>

<ShowForTs>

:::tip Using generated types

At this point, you might see an error in your Cell while trying to import from `types/graphql`: "The type ArticlesQuery does not exist"

When you have the dev server (via `yarn rw dev`) running, the CLI watches files for changes and triggers type generation automatically, but you can trigger it manually too by running:

```bash
yarn rw g types
```

This looks at your Cell's `QUERY` and—as long as it's valid—tries to automatically create a TypeScript type for you to use in your code.

:::

</ShowForTs>

Let's plug this cell into our `HomePage` and see what happens:

<Tabs groupId="js-ts">
Expand Down
60 changes: 60 additions & 0 deletions docs/versioned_docs/version-2.2/tutorial/chapter7/rbac.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,66 @@ export const getCurrentUser = async (session) => {
</TabItem>
</Tabs>
<ShowForTs>
### Fixing the hasRole function
At this point, you might notice an error in your `api/src/lib/auth.ts` file, in the `hasRole` function. TypeScript is trying to help you here, by highlighting that roles can never be an array of strings:
```ts title="api/src/lib/auth.ts"
export const hasRole = (roles: AllowedRoles): boolean => {

// ...

} else if (Array.isArray(currentUserRoles)) {
// 👇 TypeScript will now be telling you 'some' doesn't exist on type never:
// highlight-next-line
return currentUserRoles?.some((allowedRole) => roles === allowedRole)
}
}
```
This is because we now know that the type of `currentUser.roles` is a `string` based on the type being returned from Prisma. So you can safely remove the block of code where it's checking if roles is an array:
```diff title="api/src/lib/auth.ts"
export const hasRole = (roles: AllowedRoles): boolean => {
if (!isAuthenticated()) {
return false
}

const currentUserRoles = context.currentUser?.roles

if (typeof roles === 'string') {
if (typeof currentUserRoles === 'string') {
// roles to check is a string, currentUser.roles is a string
return currentUserRoles === roles
- } else if (Array.isArray(currentUserRoles)) {
- // roles to check is a string, currentUser.roles is an array
- return currentUserRoles?.some((allowedRole) => roles === allowedRole)
}
}

if (Array.isArray(roles)) {
if (Array.isArray(currentUserRoles)) {
// roles to check is an array, currentUser.roles is an array
return currentUserRoles?.some((allowedRole) =>
roles.includes(allowedRole)
)
} else if (typeof context?.currentUser?.roles === 'string') {
// roles to check is an array, currentUser.roles is a string
return roles.some(
(allowedRole) => context.currentUser?.roles === allowedRole
)
}
}

// roles not found
return false
}
```
</ShowForTs>
### Restricting Access via Routes
The easiest way to prevent access to an entire URL is via the Router. The `<Private>` component takes a prop `roles` in which you can give a list of only those role(s) that should have access:
Expand Down
12 changes: 0 additions & 12 deletions packages/auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,5 @@
"supertokens-auth-react": "0.24.4",
"typescript": "4.7.4"
},
"peerDependencies": {
"@clerk/clerk-react": "3.5.1",
"@clerk/clerk-sdk-node": "3.9.2"
},
"peerDependenciesMeta": {
"@clerk/clerk-react": {
"optional": true
},
"@clerk/clerk-sdk-node": {
"optional": true
}
},
"gitHead": "3905ed045508b861b495f8d5630d76c7a157d8f1"
}
Loading

0 comments on commit 1af2578

Please sign in to comment.