Skip to content

Commit

Permalink
Add Box OAuth provider (#1016)
Browse files Browse the repository at this point in the history
  • Loading branch information
pilcrowonpaper authored Aug 22, 2023
1 parent ca59d50 commit d04986b
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .auri/$6qq2nr4z.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
package: "@lucia-auth/oauth" # package name
type: "minor" # "major", "minor", "patch"
---

Add Box provider
150 changes: 150 additions & 0 deletions packages/oauth/src/providers/box.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import {
OAuth2ProviderAuth,
createOAuth2AuthorizationUrl,
validateOAuth2AuthorizationCode
} from "../core/oauth2.js";
import { ProviderUserAuth } from "../core/provider.js";
import { handleRequest, authorizationHeader } from "../utils/request.js";

import type { Auth } from "lucia";

type Config = {
clientId: string;
clientSecret: string;
redirectUri: string;
};

const PROVIDER_ID = "box";

export const box = <_Auth extends Auth = Auth>(
auth: _Auth,
config: Config
): BoxAuth<_Auth> => {
return new BoxAuth(auth, config);
};

export class BoxAuth<_Auth extends Auth = Auth> extends OAuth2ProviderAuth<
BoxUserAuth<_Auth>
> {
private config: Config;

constructor(auth: _Auth, config: Config) {
super(auth);

this.config = config;
}

public getAuthorizationUrl = async (): Promise<
readonly [url: URL, state: string]
> => {
return await createOAuth2AuthorizationUrl(
"https://account.box.com/api/oauth2/authorize",
{
clientId: this.config.clientId,
redirectUri: this.config.redirectUri,
scope: []
}
);
};

public validateCallback = async (
code: string
): Promise<BoxUserAuth<_Auth>> => {
const boxTokens = await this.validateAuthorizationCode(code);
const boxUser = await getBoxUser(boxTokens.accessToken);
return new BoxUserAuth(this.auth, boxUser, boxTokens);
};

private validateAuthorizationCode = async (
code: string
): Promise<BoxTokens> => {
const tokens = await validateOAuth2AuthorizationCode<{
access_token: string;
}>(code, "https://api.box.com/oauth2/token", {
clientId: this.config.clientId,
redirectUri: this.config.redirectUri,
clientPassword: {
authenticateWith: "client_secret",
clientSecret: this.config.clientSecret
}
});
return {
accessToken: tokens.access_token
};
};
}

export class BoxUserAuth<
_Auth extends Auth = Auth
> extends ProviderUserAuth<_Auth> {
public boxTokens: BoxTokens;
public boxUser: BoxUser;

constructor(auth: _Auth, boxUser: BoxUser, boxTokens: BoxTokens) {
super(auth, PROVIDER_ID, boxUser.id.toString());

this.boxTokens = boxTokens;
this.boxUser = boxUser;
}
}

const getBoxUser = async (accessToken: string): Promise<BoxUser> => {
const request = new Request("https://api.box.com/2.0/users/me", {
headers: {
Authorization: authorizationHeader("bearer", accessToken)
}
});
const boxUser = await handleRequest<BoxUser>(request);
return boxUser;
};

export type BoxTokens = {
accessToken: string;
};

export type BoxUser = {
id: string;
type: "user";
address: string;
avatar_url: string;
can_see_managed_users: boolean;
created_at: string;
enterprise: {
id: string;
type: string;
name: string;
};
external_app_user_id: string;
hostname: string;
is_exempt_from_device_limits: boolean;
is_exempt_from_login_verification: boolean;
is_external_collab_restricted: boolean;
is_platform_access_only: boolean;
is_sync_enabled: boolean;
job_title: string;
language: string;
login: string;
max_upload_size: number;
modified_at: string;
my_tags: [string];
name: string;
notification_email: {
email: string;
is_confirmed: boolean;
};
phone: string;
role: string;
space_amount: number;
space_used: number;
status:
| "active"
| "inactive"
| "cannot_delete_edit"
| "cannot_delete_edit_upload";
timezone: string;
tracking_codes: {
type: string;
name: string;
value: string;
}[];
};
3 changes: 3 additions & 0 deletions packages/oauth/src/providers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ export type {
AzureADUserAuth
} from "./azure-ad.js";

export { box } from "./box.js";
export type { BoxAuth, BoxTokens, BoxUser, BoxUserAuth } from "./box.js";

export { discord } from "./discord.js";
export type {
DiscordAuth,
Expand Down

0 comments on commit d04986b

Please sign in to comment.