Skip to content

Commit

Permalink
Merge pull request #1260 from FoalTS/v4-5-0
Browse files Browse the repository at this point in the history
v4.5.0
  • Loading branch information
LoicPoullain authored Aug 22, 2024
2 parents 7a2ee4a + c994515 commit 2520942
Show file tree
Hide file tree
Showing 197 changed files with 13,311 additions and 95,841 deletions.
8 changes: 4 additions & 4 deletions .github/CONTRIBUTING.MD
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ The framework development environment uses [lerna](https://lerna.js.org/) for ma
```sh
npm run start-docker # use `npm run stop-docker` to stop them
```
3. Install the root dependencies.
3. Install all dependencies.
```
npm install
```
4. Install the dependencies of each package and build each package.
4. Build packages.
```
npm run bootstrap
npx lerna run build
```
5. Check code format.
```
Expand Down Expand Up @@ -146,7 +146,7 @@ All of major releases are supported for at least 18 months.
### `@foal/cli` Package Structure
The directory `src/generate/` contains the source code of the commands `foal createapp` and `foal generate`.
The directory `src/generate/` contains the source code of the commands `npx @foal/cli createapp` and `npx foal generate`.
Here is the list of its sub-directories:
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ jobs:
steps:
- uses: actions/checkout@v1
- name: Start up databases
run: docker-compose up -d
run: docker compose up -d
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Use npm version 9.6
run: npm install -g [email protected]
- name: Install project dependencies
- name: Install project and package dependencies
run: npm install
- name: Install package dependencies and build packages
run: npm run bootstrap
- name: Build packages
run: npx lerna run build
- name: Create CLI symlink in the global folder
run: npm link
working-directory: packages/cli
Expand Down
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,9 @@ First install [Node.Js and npm](https://nodejs.org/en/download/).
### Create a new app

```
$ npm install -g @foal/cli
$ foal createapp my-app
$ cd my-app
$ npm run dev
npx @foal/cli createapp my-app
cd my-app
npm run dev
```

The development server is started! Go to `http://localhost:3001` and find our welcoming page!
Expand Down
110 changes: 110 additions & 0 deletions docs/blog/2024-08-22-version-4.5-release-notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
---
title: Version 4.5 release notes
author: Loïc Poullain
author_title: Creator of FoalTS. Software engineer.
author_url: https://loicpoullain.com
author_image_url: https://avatars1.githubusercontent.com/u/13604533?v=4
image: blog/twitter-banners/version-4.5-release-notes.png
tags: [release]
---

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

Version 4.5 of [Foal](https://foalts.org/) is out!

<!--truncate-->

## Asynchronous tasks

In some situations, we need to execute a specific task without waiting for it and without blocking the request.

This could be, for example, sending a specific message to the CRM or company chat. In this case, the user needs to be able to see his or her request completed as quickly as possible, even if the request to the CRM takes some time or fails.

To this end, Foal version 4.5 provides an `AsyncService` to execute these tasks asynchronously, and correctly catch and log their errors where appropriate.

```typescript
import { AsyncService, dependency } from '@foal/core';

import { CRMService } from './somewhere';

export class SubscriptionService {
@dependency
asyncService: AsyncService;

@dependency
crmService: CRMService;

async subscribe(userId: number): Promise<void> {
// Do something

this.asyncService.run(() => this.crmService.updateUser(userId));
}
}

```

## Social authentication for SPAs

If you wish to manually manage the redirection to the consent page on the client side (which is often necessary when developing an SPA), you can now do so with the `createHttpResponseWithConsentPageUrl` method. It returns an `HttpResponseOK` whose body contains the URL of the consent page.

```typescript
export class AuthController {
@dependency
google: GoogleProvider;

@Get('/signin/google')
getConsentPageURL() {
return this.google.createHttpResponseWithConsentPageUrl();
}

// ...

}

```

## Google social authentification

The typing of the `GoogleProvider` service has been improved. The `userInfo` property returned by `getUserInfo` is now typed with the values returned by the Google server.

```typescript
const { userInfo } = await this.googleProvider.getUserInfo(...);

// userInfo.email, userInfo.family_name, etc
```

## Logging improvements

In previous versions, the util function `displayServerURL` and configuration errors printed logs on several lines, which was not appropriate for logging software.

From version 4.5 onwards, configuration errors are displayed on a single line and the `displayServerURL` function is marked as deprecated.

## CLI fixes

When running `npx foal connect react` to connect the React application to the Foal application in development, the following features did not work:
- Proxify requests from the client to the server without needing to enable CORS or specify a different port in development.
- Build the client application in the server application's public directory.

This is fixed in v4.5.

## Global use of CLI deprecated

In previous versions, the tutorial suggested installing the CLI globally to create a new application or generate files. However, it is considered bad practice to install a dependency globally for local use.

In addition, the CLI was also installed locally so that the build command would work when deploying the application to a CI or to production. This was maintaining two versions of the CLI.

To correct this, in the documentation and examples, the CLI is now always installed and used locally. To use it, simply add `npx` before each command (except for `createapp`).

```bash
# Before
foal createapp my-app

foal generate script foobar
foal createsecret

# After
npx @foal/cli createapp my-app

npx foal generate script foobar
npx foal createsecret
```
Binary file added docs/blog/assets/version-4.5-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.
7 changes: 3 additions & 4 deletions docs/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,9 @@ Great attention is paid to the stability of the product. You can find out more b
## Get Started

```
> npm install -g @foal/cli
> foal createapp my-app
> cd my-app
> npm run dev
npx @foal/cli createapp my-app
cd my-app
npm run dev
```

The development server is started! Go to `http://localhost:3001` and find our welcoming page!
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/architecture/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ module.exports = {
> When creating a new project, you can also add the flag `--yaml` to have all the configuration directly generated in YAML.
>
> ```
> foal createapp my-app --yaml
> npx @foal/cli createapp my-app --yaml
> ```
>
> The extension of the YAML files must be `.yml`.
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/architecture/controllers.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: Controllers


```sh
foal generate controller my-controller
npx foal generate controller my-controller
```

```typescript
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/architecture/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: Hooks


```sh
foal generate hook my-hook
npx foal generate hook my-hook
```

## Description
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import TabItem from '@theme/TabItem';


```sh
foal generate service my-service
npx foal generate service my-service
```

```typescript
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/authentication/jwt.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ Foal offers a package, named `@foal/jwt`, to manage authentication / authorizati

## Generate & Provide a Secret

In order to use JWTs, you must provide a secret to *sign* your tokens. If you do not already have your own, you can generate one with the `foal createsecret` command.
In order to use JWTs, you must provide a secret to *sign* your tokens. If you do not already have your own, you can generate one with the `npx foal createsecret` command.

```sh
$ foal createsecret
npx foal createsecret
Ak0WcVcGuOoFuZ4oqF1tgqbW6dIAeSacIN6h7qEyJM8=
```

Expand Down
4 changes: 2 additions & 2 deletions docs/docs/authentication/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ export class ApiController {
First, generate a base64-encoded secret.

```bash
foal createsecret
npx foal createsecret
```

Save this secret in a `.env` file.
Expand Down Expand Up @@ -516,7 +516,7 @@ export class ApiController {
First, generate a base64-encoded secret.

```bash
foal createsecret
npx foal createsecret
```

Save this secret in a `.env` file.
Expand Down
8 changes: 4 additions & 4 deletions docs/docs/authentication/session-tokens.md
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ module.exports = {
#### Revoking One Session

```
foal g script revoke-session
npx foal g script revoke-session
```

Open `scripts/revoke-session.ts` and update its content.
Expand Down Expand Up @@ -675,13 +675,13 @@ npm run build
Run the script.

```
foal run revoke-session token="lfdkszjanjiznr"
npx foal run revoke-session token="lfdkszjanjiznr"
```

#### Revoking All Sessions

```
foal g script revoke-all-sessions
npx foal g script revoke-all-sessions
```

Open `scripts/revoke-all-sessions.ts` and update its content.
Expand Down Expand Up @@ -709,7 +709,7 @@ npm run build
Run the script.

```
foal run revoke-all-sessions
npx foal run revoke-all-sessions
```

### Query All Sessions of a User
Expand Down
26 changes: 14 additions & 12 deletions docs/docs/authentication/social-auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ export class AuthController {
redirectToGoogle() {
// Your "Login In with Google" button should point to this route.
// The user will be redirected to Google auth page.
return this.google.redirect();
return this.google.createHttpResponseWithConsentPageUrl({ isRedirection: true });
}

@Get('/signin/google/callback')
Expand All @@ -157,11 +157,13 @@ export class AuthController {

You can also override in the `redirect` method the scopes you want:
```typescript
return this.google.redirect({ scopes: [ 'email' ] });
return this.google.createHttpResponseWithConsentPageUrl({ isRedirection: true, scopes: [ 'email' ] });
```

Additional parameters can passed to the `redirect` and `getUserInfo` methods depending on the provider.

> If you want to manage the redirection on the client side manually, don't specify the `isRedirection` option. In this case, the `createHttpResponseWithConsentPageUrl` method returns an `HttpResponseOK` whose body contains the URL of the consent page. The name of the body property is `consentPageUrl`.
## Techniques

### Usage with sessions
Expand Down Expand Up @@ -210,15 +212,15 @@ export class AuthController {

@Get('/signin/google')
redirectToGoogle() {
return this.google.redirect();
return this.google.createHttpResponseWithConsentPageUrl({ isRedirection: true });
}

@Get('/signin/google/callback')
@UseSessions({
cookie: true,
})
async handleGoogleRedirection(ctx: Context<User>) {
const { userInfo } = await this.google.getUserInfo<{ email: string }>(ctx);
const { userInfo } = await this.google.getUserInfo(ctx);

if (!userInfo.email) {
throw new Error('Google should have returned an email address.');
Expand Down Expand Up @@ -285,12 +287,12 @@ export class AuthController {

@Get('/signin/google')
redirectToGoogle() {
return this.google.redirect();
return this.google.createHttpResponseWithConsentPageUrl({ isRedirection: true });
}

@Get('/signin/google/callback')
async handleGoogleRedirection(ctx: Context) {
const { userInfo } = await this.google.getUserInfo<{ email: string }>(ctx);
const { userInfo } = await this.google.getUserInfo(ctx);

if (!userInfo.email) {
throw new Error('Google should have returned an email address.');
Expand Down Expand Up @@ -442,11 +444,11 @@ Visit the [Google API Console](https://console.developers.google.com/apis/creden

#### Redirection parameters

The `redirect` method of the `GoogleProvider` accepts additional parameters. These parameters and their description are listed [here](https://developers.google.com/identity/protocols/OpenIDConnect#authenticationuriparameters) and are all optional.
The `createHttpResponseWithConsentPageUrl` method of the `GoogleProvider` accepts additional parameters. These parameters and their description are listed [here](https://developers.google.com/identity/protocols/OpenIDConnect#authenticationuriparameters) and are all optional.

*Example*
```typescript
this.google.redirect({ /* ... */ }, {
this.google.createHttpResponseWithConsentPageUrl({ /* ... */ }, {
access_type: 'offline'
})
```
Expand All @@ -463,11 +465,11 @@ Visit [Facebook's developer website](https://developers.facebook.com/) to create

#### Redirection parameters

The `redirect` method of the `FacebookProvider` accepts an additional `auth_type` parameter which is optional.
The `createHttpResponseWithConsentPageUrl` method of the `FacebookProvider` accepts an additional `auth_type` parameter which is optional.

*Example*
```typescript
this.facebook.redirect({ /* ... */ }, {
this.facebook.createHttpResponseWithConsentPageUrl({ /* ... */ }, {
auth_type: 'rerequest'
});
```
Expand Down Expand Up @@ -505,11 +507,11 @@ Additional documentation on Github's redirect URLs can be found [here](https://d

#### Redirection parameters

The `redirect` method of the `GithubProvider` accepts additional parameters. These parameters and their description are listed below and are all optional.
The `createHttpResponseWithConsentPageUrl` method of the `GithubProvider` accepts additional parameters. These parameters and their description are listed below and are all optional.

*Example*
```typescript
this.github.redirect({ /* ... */ }, {
this.github.createHttpResponseWithConsentPageUrl({ /* ... */ }, {
allow_signup: false
})
```
Expand Down
Loading

0 comments on commit 2520942

Please sign in to comment.