Skip to content

Commit

Permalink
Release v3.2.0 (#253)
Browse files Browse the repository at this point in the history
Co-authored-by: Hurby <[email protected]>
Co-authored-by: Marvin <[email protected]>
Co-authored-by: Christoph <[email protected]>
  • Loading branch information
4 people authored Jan 20, 2025
1 parent 91ef89f commit edf73cd
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 1 deletion.
1 change: 1 addition & 0 deletions .RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Add Synology provider ([#248](https://github.com/pilcrowonpaper/arctic/pull/248)).
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ Arctic does not strictly follow semantic versioning. While we aim to only introd
- Spotify
- Start.gg
- Strava
- Synology
- TikTok
- Tiltify
- Tumblr
Expand Down
1 change: 1 addition & 0 deletions docs/malta.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
["Spotify", "/providers/spotify"],
["Start.gg", "/providers/startgg"],
["Strava", "/providers/strava"],
["Synology", "/providers/synology"],
["TikTok", "/providers/tiktok"],
["Tiltify", "/providers/tiltify"],
["Tumblr", "/providers/tumblr"],
Expand Down
87 changes: 87 additions & 0 deletions docs/pages/providers/synology.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
---
title: "Synology"
---

# Synology

OAuth 2.0 provider for Synology SSO and OAuth Apps.

Also see the [OAuth 2.0 with PKCE](/guides/oauth2-pkce) guide.

## Prerequisites

To use this provider, you have to install [SSO Server](https://www.synology.com/en-us/dsm/packages/SSOServer) package on your Synology NAS.

There you have to:

1. Configure the base URL under which the SSO Server will be reachable
2. Enable the OIDC service
3. Create a new OAuth App

> Note: Both the _base URL_ and the _redirect URI_ have to use `https`.
## Initialization

The `baseURL` parameter is the full URL of your Synology NAS that you have configured in the SSO Server.

```ts
import * as arctic from "arctic";

const baseURL = "https://my_synology_nas.local:5001";
const baseURL = "https://sso.nas.example.com";
const synology = new arctic.Synology(baseUrl, applicationId, applicationSecret, redirectURI);
```

## Create authorization URL

```ts
import * as arctic from "arctic";

const state = arctic.generateState();
const codeVerifier = arctic.generateCodeVerifier();
const scopes = ["email", "groups", "openid"];
const url = synology.createAuthorizationURL(state, codeVerifier, scopes);
```

> Note: You can find all available scopes in `/webman/sso/.well-known/openid-configuration`
## Validate authorization code

`validateAuthorizationCode()` will either return an [`OAuth2Tokens`](/reference/main/OAuth2Tokens), or throw one of [`OAuth2RequestError`](/reference/main/OAuth2RequestError), [`ArcticFetchError`](/reference/main/ArcticFetchError), [`UnexpectedResponseError`](/reference/main/UnexpectedResponseError), or [`UnexpectedErrorResponseBodyError`](/reference/main/UnexpectedErrorResponseBodyError).

Synology returns an access token and the access token expiration.

```ts
import * as arctic from "arctic";

try {
const tokens = await synology.validateAuthorizationCode(code, codeVerifier);
const accessToken = tokens.accessToken();
const accessTokenExpiresAt = tokens.accessTokenExpiresAt();
} catch (e) {
if (e instanceof arctic.OAuth2RequestError) {
// Invalid authorization code, credentials, or redirect URI
const code = e.code;
// ...
}
if (e instanceof arctic.ArcticFetchError) {
// Failed to call `fetch()`
const cause = e.cause;
// ...
}
// Parse error
}
```

## Get user info

Use the `/webman/sso/SSOUserInfo.cgi` endpoint.

```ts
const user_info = await fetch("https://example.com/webman/sso/SSOUserInfo.cgi", {
headers: {
Authorization: `Bearer ${accessToken}`
}
});
const user = await response.json();
```
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "arctic",
"type": "module",
"version": "3.1.3",
"version": "3.2.0",
"description": "OAuth 2.0 clients for popular providers",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export { Slack } from "./providers/slack.js";
export { Spotify } from "./providers/spotify.js";
export { StartGG } from "./providers/startgg.js";
export { Strava } from "./providers/strava.js";
export { Synology } from "./providers/synology.js";
export { TikTok } from "./providers/tiktok.js";
export { Tiltify } from "./providers/tiltify.js";
export { Tumblr } from "./providers/tumblr.js";
Expand Down
46 changes: 46 additions & 0 deletions src/providers/synology.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { CodeChallengeMethod, OAuth2Client } from "../client.js";
import { joinURIAndPath } from "../request.js";

import type { OAuth2Tokens } from "../oauth2.js";

export class Synology {
private authorizationEndpoint: string;
private tokenEndpoint: string;

private client: OAuth2Client;

constructor(
baseURL: string,
applicationId: string,
applicationSecret: string,
redirectURI: string
) {
this.authorizationEndpoint = joinURIAndPath(baseURL, "/webman/sso/SSOOauth.cgi");
this.tokenEndpoint = joinURIAndPath(baseURL, "/webman/sso/SSOAccessToken.cgi");

this.client = new OAuth2Client(applicationId, applicationSecret, redirectURI);
}

public createAuthorizationURL(state: string, codeVerifier: string, scopes: string[]): URL {
const url = this.client.createAuthorizationURLWithPKCE(
this.authorizationEndpoint,
state,
CodeChallengeMethod.S256,
codeVerifier,
scopes
);
return url;
}

public async validateAuthorizationCode(
code: string,
codeVerifier: string
): Promise<OAuth2Tokens> {
const tokens = await this.client.validateAuthorizationCode(
this.tokenEndpoint,
code,
codeVerifier
);
return tokens;
}
}

0 comments on commit edf73cd

Please sign in to comment.