Skip to content

Commit

Permalink
Merge branch 'main' into ds-revert-auth-provider-refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
jtoar authored Aug 9, 2022
2 parents 14ddc26 + 648356c commit b33ef7e
Show file tree
Hide file tree
Showing 93 changed files with 5,564 additions and 3,137 deletions.
2 changes: 1 addition & 1 deletion .github/actions/check_test_project_fixture/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "check_test_project_fixture",
"private": true,
"dependencies": {
"@actions/core": "1.9.0",
"@actions/core": "1.9.1",
"@actions/exec": "1.1.1"
},
"packageManager": "[email protected]"
Expand Down
20 changes: 15 additions & 5 deletions .github/actions/check_test_project_fixture/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ __metadata:
version: 6
cacheKey: 8c0

"@actions/core@npm:1.9.0":
version: 1.9.0
resolution: "@actions/core@npm:1.9.0"
"@actions/core@npm:1.9.1":
version: 1.9.1
resolution: "@actions/core@npm:1.9.1"
dependencies:
"@actions/http-client": ^2.0.1
checksum: 66a238981d7f9aa3c8ca0d80eb87aa291203dabd5c8e60e50d5075632c643883337f342fd677470d6cfd3588c483f32897fbb5c03a400b9c60171a32d2cbeb8d
uuid: ^8.3.2
checksum: 9e568d0df7d659ad0738da66f167d411714f7351fab527fcb91dd6afbeb58006e6cf1f752adc567aab1b9043f96581b2457746f394f7a756f7b14b554d7c4710
languageName: node
linkType: hard

Expand Down Expand Up @@ -43,7 +44,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "check_test_project_fixture@workspace:."
dependencies:
"@actions/core": 1.9.0
"@actions/core": 1.9.1
"@actions/exec": 1.1.1
languageName: unknown
linkType: soft
Expand All @@ -54,3 +55,12 @@ __metadata:
checksum: e27e7e896f2426c1c747325b5f54efebc1a004647d853fad892b46d64e37591ccd0b97439470795e5262b5c0748d22beb4489a04a0a448029636670bfd801b75
languageName: node
linkType: hard

"uuid@npm:^8.3.2":
version: 8.3.2
resolution: "uuid@npm:8.3.2"
bin:
uuid: dist/bin/uuid
checksum: bcbb807a917d374a49f475fae2e87fdca7da5e5530820ef53f65ba1d12131bd81a92ecf259cc7ce317cbe0f289e7d79fdfebcef9bfa3087c8c8a2fa304c9be54
languageName: node
linkType: hard
2 changes: 1 addition & 1 deletion .github/actions/only_doc_changes/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "only_doc_changes",
"private": true,
"dependencies": {
"@actions/core": "1.9.0",
"@actions/core": "1.9.1",
"@actions/exec": "1.1.1"
},
"packageManager": "[email protected]"
Expand Down
20 changes: 15 additions & 5 deletions .github/actions/only_doc_changes/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ __metadata:
version: 6
cacheKey: 8c0

"@actions/core@npm:1.9.0":
version: 1.9.0
resolution: "@actions/core@npm:1.9.0"
"@actions/core@npm:1.9.1":
version: 1.9.1
resolution: "@actions/core@npm:1.9.1"
dependencies:
"@actions/http-client": ^2.0.1
checksum: 66a238981d7f9aa3c8ca0d80eb87aa291203dabd5c8e60e50d5075632c643883337f342fd677470d6cfd3588c483f32897fbb5c03a400b9c60171a32d2cbeb8d
uuid: ^8.3.2
checksum: 9e568d0df7d659ad0738da66f167d411714f7351fab527fcb91dd6afbeb58006e6cf1f752adc567aab1b9043f96581b2457746f394f7a756f7b14b554d7c4710
languageName: node
linkType: hard

Expand Down Expand Up @@ -43,7 +44,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "only_doc_changes@workspace:."
dependencies:
"@actions/core": 1.9.0
"@actions/core": 1.9.1
"@actions/exec": 1.1.1
languageName: unknown
linkType: soft
Expand All @@ -54,3 +55,12 @@ __metadata:
checksum: e27e7e896f2426c1c747325b5f54efebc1a004647d853fad892b46d64e37591ccd0b97439470795e5262b5c0748d22beb4489a04a0a448029636670bfd801b75
languageName: node
linkType: hard

"uuid@npm:^8.3.2":
version: 8.3.2
resolution: "uuid@npm:8.3.2"
bin:
uuid: dist/bin/uuid
checksum: bcbb807a917d374a49f475fae2e87fdca7da5e5530820ef53f65ba1d12131bd81a92ecf259cc7ce317cbe0f289e7d79fdfebcef9bfa3087c8c8a2fa304c9be54
languageName: node
linkType: hard
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ You'll almost always want to test the functionality of your changes to the Redwo
- run `yarn create redwood-app ./redwood-project`
- `git clone` the [RedwoodJS Tutorial Blog](https://github.com/redwoodjs/redwood-tutorial)
- use a project you've already created
- create a functional test project using `yarn run build:test-project <project directory>` 👀
- create a functional test project: go to the location of your local copy of the Redwood Framework and use `yarn run build:test-project <project directory>` 👀

**Using the functional test project might be the fastest and easiest way to test your changes.**

Expand Down Expand Up @@ -102,7 +102,7 @@ cd redwood-project
RWFW_PATH=~/redwood yarn rwfw project:sync
```
Where <framework directory> is the path to your local copy of the Redwood Framework. Once provided to `rwfw`, it'll remember it and you shouldn't have to provide it again unless you move it.
Where `~/redwood` is the path to your local copy of the Redwood Framework. Once provided to `rwfw`, it'll remember it and you shouldn't have to provide it again unless you move it.

As `project:sync` starts up, it'll start logging to the console. In order, it:

Expand Down
5 changes: 4 additions & 1 deletion __fixtures__/test-project/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,8 @@
"prisma": {
"seed": "yarn rw exec seed"
},
"packageManager": "[email protected]"
"packageManager": "[email protected]",
"resolutions": {
"jest": "28.1.3"
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { render, screen } from '@redwoodjs/testing/web'
import { render } from '@redwoodjs/testing/web'

import { Loading, Empty, Failure, Success } from './BlogPostCell'
import { standard } from './BlogPostCell.mock'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { render, screen } from '@redwoodjs/testing/web'
import { render } from '@redwoodjs/testing/web'

import { Loading, Empty, Failure, Success } from './BlogPostsCell'
import { standard } from './BlogPostsCell.mock'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { render, screen } from '@redwoodjs/testing/web'
import { render } from '@redwoodjs/testing/web'

import { Loading, Empty, Failure, Success } from './WaterfallBlogPostCell'
import { standard } from './WaterfallBlogPostCell.mock'
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/cli-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -1826,15 +1826,15 @@ yarn redwood setup tsconfig
### setup ui
Set up a UI design or style library. Right now the choices are [Chakra UI](https://chakra-ui.com/), [TailwindCSS](https://tailwindcss.com/) and [WindiCSS](https://windicss.org/).
Set up a UI design or style library. Right now the choices are [TailwindCSS](https://tailwindcss.com/), [Chakra UI](https://chakra-ui.com/), [Mantine UI](https://ui.mantine.dev/) and [WindiCSS](https://windicss.org/).
```
yarn rw setup ui <library>
```
| Arguments & Options | Description |
| :------------------ | :-------------------------------------------------------------------------- |
| `library` | Library to configure. Choices are `chakra-ui`, `tailwindcss` and `windicss` |
| `library` | Library to configure. Choices are `chakra-ui`, `tailwindcss`, `mantine`, and `windicss` |
| `--force, -f` | Overwrite existing configuration |
## storybook
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ description: How to use environment variables on the api and web sides

You can provide environment variables to each side of your Redwood app in different ways, depending on each Side's target, and whether you're in development or production.

> Right now, Redwood apps have two fixed Sides, API and Web, that have each have a single target, nodejs and browser respectively.
> Right now, Redwood apps have two fixed Sides, API and Web, that each have a single target, nodejs and browser respectively.
## Generally

Expand Down Expand Up @@ -46,7 +46,7 @@ By adding environment variables to this array, they'll be available to Web in pr

Note: if someone inspects your site's source, _they could see your `REDWOOD_ENV_SECRET_API_KEY` in plain text._ This is a limitation of delivering static JS and HTML to the browser.

#### Option 2: Prefixing with REDWOOD*ENV*
#### Option 2: Prefixing with REDWOOD\_ENV\_

In `.env`, if you prefix your environment variables with `REDWOOD_ENV_`, they'll be available via `process.env.REDWOOD_ENV_MY_VAR_NAME`, and will be dynamically replaced at built-time.

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/graphql.md
Original file line number Diff line number Diff line change
Expand Up @@ -677,7 +677,7 @@ export const schema = gql`
2. Import the scalar's definition and resolver and pass them to your GraphQLHandler via the `schemaOptions` property:
```tsx {11-14} title="api/src/functions/graphql.ts"
```tsx {10-13} title="api/src/functions/graphql.ts"
import { CurrencyDefinition, CurrencyResolver } from 'graphql-scalars'

// ...
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/how-to/self-hosting-redwood.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ To self-host, you'll have to do a bit of configuration both to your Redwood app
First add PM2 as a dev dependency to your project root:

```termninal
yarn add -DW pm2
yarn add -D pm2
```

Then create a PM2 ecosystem configuration file. For clarity, it's recommended to rename `ecosystem.config.js` to something like `pm2.config.js`:
Expand Down
4 changes: 4 additions & 0 deletions docs/docs/how-to/sending-emails.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,10 @@ And then in the users service we'll just create a dummy method to start with.
```ts title="users.ts"
// ...

import type { Prisma } from '@prisma/client'

// ...

export const emailUser = async ({ id }: Prisma.UserWhereUniqueInput) => {
const user = await db.user.findUnique({
where: { id },
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/serverless-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ export const handler = useRequireAuth({

Now anywhere `context` is used, such as in services or when using `hasRole()` or `isAuthenticated()` from your `auth` lib, `currentUser` will be set and `requireAuth`-related functions will be able to verify the authentication state or if the user has the required roles.

In short, you can now use the any of your auth functions like `isAuthenticated()`, `hasRole()`, or `requireAuth()` in your serverless function.
In short, you can now use any of your auth functions like `isAuthenticated()`, `hasRole()`, or `requireAuth()` in your serverless function.

:::note

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/services.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Remember: Service are just functions. That means they can be used not only as Gr
>
> The short answer is no because our build process doesn't support it yet.
>
> Generally, in a full-stack application, Services will concern themselves with getting data in and out of a database. The libraries we use for this, like Prisma, do not run in the browser. However, even if it did, it would happily pass on whatever SQL-equivalent commands you give it, like `db.user.deleteMany()`, which would remove all user records! That kind of power in the hands of the client would wreck havoc the likes of which you have never seen.
> Generally, in a full-stack application, Services will concern themselves with getting data in and out of a database. The libraries we use for this, like Prisma, do not run in the browser. However, even if it did, it would happily pass on whatever SQL-equivalent commands you give it, like `db.user.deleteMany()`, which would remove all user records! That kind of power in the hands of the client would wreak havoc the likes of which you have never seen.
Service functions can also call each other. For example, that theoretical Service function that handles transferring money between two accounts: it certainly comes in handy when a user initiates a transfer through a GraphQL call, but our business logic for what constitutes a transfer lives in that function. That function should be the only one responsible for moving money between two accounts, so we should make use of it anywhere we need to do a transfer—imagine an async task that moves $100 between a checking and savings account every 1st of the month.

Expand Down
10 changes: 5 additions & 5 deletions docs/docs/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ export default Article

If we're only displaying the summary of an article then we'll only show the first 100 characters with an ellipsis on the end ("...") and include a link to "Read more" to see the full article. A reasonable test for this component would be that when the `summary` prop is `true` then the "Read more" text should be present. If `summary` is `false` then it should *not* be present. That's where `queryByText()` comes in (relevant test lines are highlighted):

```jsx {18,24} title="web/src/components/Article/Article.test.js"
```jsx {22} title="web/src/components/Article/Article.test.js"
import { render, screen } from '@redwoodjs/testing/web'
import Article from 'src/components/Article'

Expand Down Expand Up @@ -478,7 +478,7 @@ it('renders a link with a name', () => {

But what if we wanted to check the `href` of the link itself to be sure it's correct? In that case we can capture the `screen.getByRole()` return and run expectations on that as well (the `forEach()` loop has been removed here for simplicity):

```jsx {2,6-8}
```jsx {1,6-8}
import { routes } from '@redwoodjs/router'

it('renders a link with a name', () => {
Expand Down Expand Up @@ -597,7 +597,7 @@ export default Article

Redwood provides the test function `mockGraphQLQuery()` for providing the result of a given named GraphQL. In this case our query is named `getArticle` and we can mock that in our test as follows:

```jsx {8-16,20} title="web/src/components/Article/Article.test.js"
```jsx {6-14,18} title="web/src/components/Article/Article.test.js"
import { render, screen } from '@redwoodjs/testing/web'
import Article from 'src/components/Article'

Expand Down Expand Up @@ -646,7 +646,7 @@ mockGraphQLQuery('getArticle', (variables, { ctx }) => {

You could then test that you show a proper error message in your component:

```jsx {4,8-10,21,27} title="web/src/components/Article/Article.js"
```jsx {2,6-8,18-20,24} title="web/src/components/Article/Article.js"
const Article = ({ id }) => {
const { data, error } = useQuery(GET_ARTICLE, {
variables: { id },
Expand Down Expand Up @@ -1433,7 +1433,7 @@ scenario('incomplete', 'retrieves only incomplete users', async (scenario) => {
})
```
The name of the scenario you want to use is passed as the *first* argument to `scenario()` and now those will be the only records present in the database at the time the test to run. Assume that the `users()` function contains some logic to determine whether a user record is "complete" or not. If you pass `{ complete: false }` then it should return only those that it determines are not complete, which in this case includes users who have not entered their name yet. We seed the database with the scenario where one user is complete and one is not, then check that the return of `users()` only contains the user without the name.
The name of the scenario you want to use is passed as the *first* argument to `scenario()` and now those will be the only records present in the database at the time the test is run. Assume that the `users()` function contains some logic to determine whether a user record is "complete" or not. If you pass `{ complete: false }` then it should return only those that it determines are not complete, which in this case includes users who have not entered their name yet. We seed the database with the scenario where one user is complete and one is not, then check that the return of `users()` only contains the user without the name.
#### Multiple Models
Expand Down
37 changes: 7 additions & 30 deletions docs/docs/tutorial/chapter4/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ export const isAuthenticated = () => {
return !!context.currentUser
}

export const hasRole = ({ roles }) => {
export const hasRole = (roles) => {
if (!isAuthenticated()) {
return false
}
Expand All @@ -751,7 +751,7 @@ export const hasRole = ({ roles }) => {
return currentUserRoles?.some((allowedRole) =>
roles.includes(allowedRole)
)
} else if (typeof context.currentUser.roles === 'string') {
} 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
Expand All @@ -773,25 +773,16 @@ export const requireAuth = ({ roles }) => {
}
}
```
:::caution
At this point of the tutorial we have **not added roles** to our user model yet, therefore you can ignore the `hasRole` method in `api/src/lib/auth.js` for now.
If this bothers you, feel free to peek into [the tutorial chapter about Authorization](../chapter7/rbac.md) and add the missing field as described there.
:::
</TabItem>
<TabItem value="ts" label="TypeScript">
```ts title="api/src/lib/auth.ts"
import { AuthenticationError, ForbiddenError } from '@redwoodjs/graphql-server'
import { db } from './db'

export const getCurrentUser = async (session) => {
import type { DbAuthSession } from '@redwoodjs/api'

export const getCurrentUser = async (session: DbAuthSession<number>) => {
return await db.user.findUnique({
where: { id: session.id },
select: { id: true },
Expand All @@ -804,7 +795,7 @@ export const isAuthenticated = (): boolean => {

type AllowedRoles = string | string[] | undefined

export const hasRole = ({ roles }): boolean => {
export const hasRole = (roles: AllowedRoles): boolean => {
if (!isAuthenticated()) {
return false
}
Expand All @@ -827,7 +818,7 @@ export const hasRole = ({ roles }): boolean => {
return currentUserRoles?.some((allowedRole) =>
roles.includes(allowedRole)
)
} else if (typeof context.currentUser.roles === 'string') {
} 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
Expand All @@ -849,23 +840,9 @@ export const requireAuth = ({ roles }: { roles?: AllowedRoles } = {}) => {
}
}
```
:::caution
At this point of the tutorial we have **not added roles** to our user model yet, therefore you can ignore the following error:
`Property 'roles' does not exist on type '{ id: number; email: string; }'.`
in the `hasRole` method in `api/src/lib/auth.ts` for now.
If this bothers you, feel free to peek into [the tutorial chapter about Authorization](../chapter7/rbac.md) and add the missing field as described there.
:::
</TabItem>
</Tabs>
The `getCurrentUser()` function is where the magic happens: whatever is returned by this function is the content of `currentUser`, in both the web and api sides! In the case of dbAuth, the single argument passed in, `session`, contains the `id` of the user that's logged in. It then looks up the user in the database with Prisma, selecting just the `id`. Let's add `email` to this list:
<Tabs groupId="js-ts">
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/typescript/strict-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ You'll have to adjust the generated code depending on your User model.
#### A. If your project does not use roles
If your `getCurrentUser` doesn't return `roles`, and you don't use this functionality, you can safely remove the `hasRoles` function.
If your `getCurrentUser` doesn't return `roles`, and you don't use this functionality, you can safely remove the `hasRole` function.
#### B. Roles on current user is a string
Expand Down
8 changes: 4 additions & 4 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@
]
},
"dependencies": {
"@docusaurus/core": "2.0.0-rc.1",
"@docusaurus/plugin-content-docs": "2.0.0-rc.1",
"@docusaurus/preset-classic": "2.0.0-rc.1",
"@docusaurus/core": "2.0.1",
"@docusaurus/plugin-content-docs": "2.0.1",
"@docusaurus/preset-classic": "2.0.1",
"@mdx-js/react": "1.6.22",
"clsx": "1.2.1",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-player": "2.10.1"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "2.0.0-rc.1",
"@docusaurus/module-type-aliases": "2.0.1",
"@tsconfig/docusaurus": "1.0.6",
"typescript": "4.7.4"
}
Expand Down
Loading

0 comments on commit b33ef7e

Please sign in to comment.