# TypeScript SDK v2.0 Major Release

## Key Release Notes

1. [PKCE](https://www.rfc-editor.org/rfc/rfc7636) is introduced, and its implementation is mandated. According to [**OAuth 2.0 Security Best Current Practice**](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#name-authorization-code-grant)**:**

   > For confidential clients, the use of PKCE \[[RFC7636](https://www.rfc-editor.org/info/rfc7636)] is RECOMMENDED, as it provides a strong protection against misuse and injection of authorisation codes as described in [Section 4.5.3.1](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#pkce_as_injection_protection) and, as a side-effect, prevents CSRF even in presence of strong attackers as described in [Section 4.7.1](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#csrf_countermeasures).
2. `SgidClient.authorizationUrl()`, `SgidClient.callback()`, and `SgidClient.userinfo()` now take in a single [options object](https://www.codereadability.com/what-are-javascript-options-objects/) as a parameter, instead of sequential, possibly optional parameters. Refer to SgidClient’s module file `SgidClient.d.ts` for implementatino details.
3. `sub` is now required in `userinfo()` calls, which can be retrieved from the response returned from `callback()` .
4. In light of all the breaking changes above, users are strongly recommended to refer to the example upgrade path outlined below to safely migrate their applications to v2.x SDK. Deprecation of the v1.x SDK will take place in **31st December 2023**, therefore **any existing users who has yet to upgrade their SDK version by then will face disruptions in their application(s).**
5. The [Developer Documentation](https://docs.id.gov.sg/integrations-with-sgid/typescript-javascript) has been revamped, containing the newest changes. Users can refer to the documentation for a better understanding of how sgID works.

## Upgrade Path

The code below assumes the following contexts for Client Application:

* Client Application is a full stack web application.
* Client Application consists of a SPA and an Express back-end server.
* Client Application manages state in its back-end server's session.

Refer to the [Framework Guides Section](https://docs.id.gov.sg/integrations-with-sgid/typescript-javascript) for how a Next.js implementation might look like.

### Installing the Latest Release

Run `npm i @opengovsg/sgid-client@2.0.0` (or any newer minor/patch versions released in the future) for all directories that

* contain a `package.json` file, and
* have a dependency to `@opengovsg/sgid-client` in the corresponding `package.json` file.

### Authorization Request (`authorizationUrl(…)`)

For every OAuth request, generate a PKCE pair (consisting of code challenge and code verifier). **Do not reuse the same PKCE pairs for any requests.**

Call `authorizationUrl()` with the correct options object.

#### Before (DO NOT COPY):

<pre class="language-typescript"><code class="lang-typescript"><strong>// Generate an authorization URL
</strong>  const { url, nonce } = sgid.authorizationUrl(
    state,
    ['openid', 'myinfo.name']
    )
</code></pre>

#### After:

```typescript
// Generate a PKCE pair
  const { codeChallenge, codeVerifier } = generatePkcePair()
  
// Generate an authorization URL
  const { url, nonce } = sgid.authorizationUrl({
    state,
    codeChallenge,
    scope: ['openid', 'myinfo.name']
    })
```

Store the code[^1]Verifier with the corresponding session ID, alongside its state and nonce if applicable:

```typescript
// Store session data
sessionData[sessionId] = {
    state,
    nonce,
    codeVerifier
}
```

### Access Token Request (`callback(…)`)

Retrieve the code verifier from the session and pass it in `callback()`as part of the options object.

#### Before (DO NOT COPY):

```typescript
// Exchange the authorization code and code verifier for the access token
const { accessToken, sub } = await sgid.callback(code, session.nonce)
```

#### After:

<pre class="language-typescript"><code class="lang-typescript"><strong>// Exchange the authorization code and code verifier for the access token
</strong>const { accessToken, sub } = await sgid.callback({
  code,
  nonce: session.nonce,
  codeVerifier: session.codeVerifier,
})
</code></pre>

### Retrieving User info (`userinfo(…)`)

Note the inclusion of `sub` as one of the fields in the options object.

#### Before (DO NOT COPY):

<pre class="language-tsx" data-full-width="false"><code class="lang-tsx"><strong>//Request user info using the access token
</strong>const userinfo = await sgid.userinfo(accessToken)
</code></pre>

#### After:

```typescript
//Request user info using the access token
const userinfo = await sgid.userinfo({
  accessToken,
  sub
})
```

### Congratulations!&#x20;

You should have the v2 SDK successfully integrated into your application!

## FAQ

**Q: What if my application does not follow the same architecture as the example Application described?**

A: Unfortunately it is infeasible to list out all possible upgrade paths as there are too many possible architectures for an application in practice. However, the example upgrade path should serve as an adequate reference guide for the necessary changes to migrate to v2 SDK.

**Q: I'm stuck at Step X and I don't know what to do. How can I proceed?**

A: Feel free to drop us a message at this [form](https://go.gov.sg/sgid-contact) for further clarification.

[^1]:
