Skip to content

Commit

Permalink
Merge branch 'master' into v3-0-0
Browse files Browse the repository at this point in the history
  • Loading branch information
LoicPoullain committed May 29, 2022
2 parents eeb37d0 + d64c6b5 commit b526fc4
Show file tree
Hide file tree
Showing 58 changed files with 444 additions and 85 deletions.
62 changes: 62 additions & 0 deletions docs/blog/2022-05-29-version-2.9-release-notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
title: Version 2.9 release notes
author: Loïc Poullain
author_title: Fullstack developer and creator of FoalTS
author_url: https://github.com/LoicPoullain
author_image_url: https://avatars1.githubusercontent.com/u/13604533?v=4
image: blog/twitter-banners/version-2.9-release-notes.png
tags: [release]
---

![Banner](./assets/version-2.9-is-here/banner.png)

Version 2.9 of [Foal](https://foalts.org/) has been released! Here are the improvements that it brings.

<!--truncate-->

## New OAuth2 Twitter Provider

After LinkedIn, Google, Github and Facebook, Foal now supports Twitter for social authentication.

👉 [Link to the documentation](https://foalts.org/docs/authentication-and-access-control/social-auth/)

A big thanks to [@LeonardoSalvucci](https://github.com/LeonardoSalvucci) for having implemented this feature.

```typescript
// 3p
import { Context, dependency, Get } from '@foal/core';
import { TwitterProvider } from '@foal/social';

export class AuthController {
@dependency
twitter: TwitterProvider;

@Get('/signin/twitter')
redirectToTwitter() {
// Your "Login In with Twitter" button should point to this route.
// The user will be redirected to Twitter auth page.
return this.twitter.redirect();
}

@Get('/signin/twitter/callback')
async handleTwitterRedirection(ctx: Context) {
// Once the user gives their permission to log in with Twitter, the OAuth server
// will redirect the user to this route. This route must match the redirect URI.
const { userInfo, tokens } = await this.twitter.getUserInfo(ctx);

// Do something with the user information AND/OR the access token.
// If you only need the access token, you can call the "getTokens" method.

// The method usually ends with a HttpResponseRedirect object as returned value.
}

}
```

## OAuth2 Providers support PKCE Code Flow

OAuth2 abstract provider now supports PKCE code flow. If you wish to implement your own provider using PKCE, it's now possible!

## Support for version 15 of `graphql` and latest version of `type-graphql`

Foal's dependencies have been updated so as to support the latest version of [TypeGraphQL](https://typegraphql.com/).
Binary file added docs/blog/assets/version-2.9-is-here/banner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/blog/assets/version-2.9-is-here/twitter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions docs/docs/authentication-and-access-control/social-auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -367,10 +367,14 @@ export class GithubProvider extends AbstractProvider<GithubAuthParameter, Github

### Sending the Client Credentials in an Authorization Header

> *This feature is available from version 2.9 onwards.*
When requesting the token endpoint, the provider sends the client ID and secret as a query parameter by default. If you want to send them in an `Authorization` header using the *basic* scheme, you can do so by setting the `useAuthorizationHeaderForTokenEndpoint` property to `true`.

### Enabling Code Flow with PKCE

> *This feature is available from version 2.9 onwards.*
If you want to enable code flow with PKCE, you can do so by setting the `usePKCE` property to `true`.

> By default, the provider will perform a SHA256 hash to generate the code challenge. If you wish to use the plaintext code verifier string as code challenge, you can do so by setting the `useCodeVerifierAsCodeChallenge` property to `true`.
Expand Down Expand Up @@ -549,6 +553,8 @@ const { userInfo } = await this.linkedin.getUserInfo(ctx, {

### Twitter

> *This feature is available from version 2.9 onwards.*
|Service name| Default scopes | Available scopes |
|---|---|---|
| `TwitterProvider` | `users.read tweet.read` | [API documentation](https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-me) |
Expand Down
2 changes: 1 addition & 1 deletion docs/i18n/es/docusaurus-plugin-content-docs/current.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"version.label": {
"message": "2.8.2 (última)",
"message": "2.9.0 (última)",
"description": "The label for version current"
},
"sidebar.someSidebar.category.TUTORIALS": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ title: GraphQL
To use GraphQL with FoalTS, you need to install the packages `graphql` and `@foal/graphql`. The first one is maintained by the GraphQL community and parses and resolves queries. The second is specific to FoalTS and allows you to configure a controller compatible with common GraphQL clients ([graphql-request](https://www.npmjs.com/package/graphql-request), [Apollo Client](https://www.apollographql.com/docs/react/), etc), load type definitions from separate files or handle errors thrown in resolvers.

```bash
npm install graphql@15 @foal/graphql
# OR
npm install graphql@14 @foal/graphql
```

Expand Down Expand Up @@ -419,6 +421,17 @@ export class ApiController extends GraphQLController {

## Using TypeGraphQL


:::info

TypeGraphQL requires version 15 of the `graphql` package:

```bash
npm install graphql@15
```

:::

> *[TypeGraphQL](https://typegraphql.com/) is a library that allows you to create GraphQL schemas and resolvers with TypeScript classes and decorators.*
You can use TypeGraphQL by simply calling its `buildSchema` function.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ In addition to traditional password authentication, Foal provides services to au
- Facebook
- Github
- Linkedin
- Twitter

If your provider is not listed here but supports OAuth 2.0, then you can still [extend the `AbstractProvider`](#custom-provider) class to integrate it or use a [community provider](#community-providers) below.

Expand Down Expand Up @@ -364,6 +365,73 @@ export class GithubProvider extends AbstractProvider<GithubAuthParameter, Github
}
```

### Sending the Client Credentials in an Authorization Header

> *This feature is available from version 2.9 onwards.*
When requesting the token endpoint, the provider sends the client ID and secret as a query parameter by default. If you want to send them in an `Authorization` header using the *basic* scheme, you can do so by setting the `useAuthorizationHeaderForTokenEndpoint` property to `true`.

### Enabling Code Flow with PKCE

> *This feature is available from version 2.9 onwards.*
If you want to enable code flow with PKCE, you can do so by setting the `usePKCE` property to `true`.

> By default, the provider will perform a SHA256 hash to generate the code challenge. If you wish to use the plaintext code verifier string as code challenge, you can do so by setting the `useCodeVerifierAsCodeChallenge` property to `true`.
When using this feature, the provider encrypts the code verifier and stores it in a cookie on the client. In order to do this, you need to provide a secret using the configuration key `settings.social.secret.codeVerifierSecret`.

<Tabs
defaultValue="yaml"
values={[
{label: 'YAML', value: 'yaml'},
{label: 'JSON', value: 'json'},
{label: 'JS', value: 'js'},
]}
>
<TabItem value="yaml">
```yaml
settings:
social:
secret:
codeVerifierSecret: 'xxx'
```
</TabItem>
<TabItem value="json">
```json
{
"settings": {
"social": {
"secret": {
"codeVerifierSecret": "xxx"
}
}
}
}
```

</TabItem>
<TabItem value="js">

```javascript
module.exports = {
settings: {
social: {
secret: {
codeVerifierSecret: 'xxx'
}
}
}
}
```

</TabItem>
</Tabs>


## Official Providers

### Google
Expand Down Expand Up @@ -483,6 +551,19 @@ const { userInfo } = await this.linkedin.getUserInfo(ctx, {
| `fields` | `string[]` | List of fields that the returned user info object should contain. Additional documentation on [field projections](https://developer.linkedin.com/docs/guide/v2/concepts/projections). |
| `projection` | `string` | LinkedIn projection parameter. |

### Twitter

> *This feature is available from version 2.9 onwards.*
|Service name| Default scopes | Available scopes |
|---|---|---|
| `TwitterProvider` | `users.read tweet.read` | [API documentation](https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-me) |

#### Register an OAuth application

Visit [this page](https://developer.twitter.com/en/portal/dashboard) to create an application and obtain a client ID and a client secret. You must configure Oauth2 settings to be used with public client;


## Community Providers

There are no community providers available yet! If you want to share one, feel free to [open a PR](https://github.com/FoalTS/foal) on Github.
Expand All @@ -492,6 +573,7 @@ There are no community providers available yet! If you want to share one, feel f
| Error | Description |
| --- | --- |
| `InvalidStateError` | The `state` query does not match the value found in the cookie. |
| `CodeVerifierNotFound` | The encrypted code verifier was not found in the cookie (only when using PKCE). |
| `AuthorizationError` | The authorization server returns an error. This can happen when a user does not give consent on the provider page. |
| `UserInfoError` | Thrown in `AbstractProvider.getUserFromTokens` if the request to the resource server is unsuccessful. |

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ tsconfig.app.json

Then you will need to run `npm install` and `npm run build`.

> If you get an error such as `Foal not found error`, it is probably because the dev dependencies (which include the `@foal/cli` package) have not been installed. To force the installation of these dependencies, you can use the following command: `npm install --production=false`.
If you install dependencies and build the app on your local host directly, then you should upload these files:

```sh
Expand All @@ -84,4 +86,4 @@ ormconfig.js
package-lock.json
package.json
public/ # this may depend on how the platform manages static files
```
```
2 changes: 1 addition & 1 deletion docs/i18n/fr/docusaurus-plugin-content-docs/current.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"version.label": {
"message": "2.8.2 (latest)",
"message": "2.9.0 (latest)",
"description": "The label for version current"
},
"sidebar.someSidebar.category.TUTORIALS": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ title: GraphQL
To use GraphQL with FoalTS, you need to install the packages `graphql` and `@foal/graphql`. The first one is maintained by the GraphQL community and parses and resolves queries. The second is specific to FoalTS and allows you to configure a controller compatible with common GraphQL clients ([graphql-request](https://www.npmjs.com/package/graphql-request), [Apollo Client](https://www.apollographql.com/docs/react/), etc), load type definitions from separate files or handle errors thrown in resolvers.

```bash
npm install graphql@15 @foal/graphql
# OR
npm install graphql@14 @foal/graphql
```

Expand Down Expand Up @@ -419,6 +421,17 @@ export class ApiController extends GraphQLController {

## Using TypeGraphQL


:::info

TypeGraphQL requires version 15 of the `graphql` package:

```bash
npm install graphql@15
```

:::

> *[TypeGraphQL](https://typegraphql.com/) is a library that allows you to create GraphQL schemas and resolvers with TypeScript classes and decorators.*
You can use TypeGraphQL by simply calling its `buildSchema` function.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export async function main(args: { codeName: string, name: string }) {

try {
console.log(
await permission.save();
await permission.save()
);
} catch (error: any) {
console.log(error.message);
Expand Down Expand Up @@ -388,4 +388,4 @@ The class `UserWithPermissions` provides a static method `withPerm` to get all u
class User extends UserWithPermissions {}

const users = await User.withPerm<User>('perm1');
```
```
Loading

0 comments on commit b526fc4

Please sign in to comment.