antarctic 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/LICENSE +24 -0
  2. package/README.md +155 -0
  3. package/dist/auth.d.ts +63 -0
  4. package/dist/auth.js +191 -0
  5. package/dist/client.d.ts +16 -0
  6. package/dist/client.js +105 -0
  7. package/dist/index.d.ts +70 -0
  8. package/dist/index.js +69 -0
  9. package/dist/oauth2.d.ts +16 -0
  10. package/dist/oauth2.js +67 -0
  11. package/dist/oidc.d.ts +1 -0
  12. package/dist/oidc.js +11 -0
  13. package/dist/providers/42.d.ts +16 -0
  14. package/dist/providers/42.js +75 -0
  15. package/dist/providers/amazon-cognito.d.ts +21 -0
  16. package/dist/providers/amazon-cognito.js +76 -0
  17. package/dist/providers/anilist.d.ts +14 -0
  18. package/dist/providers/anilist.js +91 -0
  19. package/dist/providers/apple.d.ts +22 -0
  20. package/dist/providers/apple.js +106 -0
  21. package/dist/providers/atlassian.d.ts +17 -0
  22. package/dist/providers/atlassian.js +83 -0
  23. package/dist/providers/auth0.d.ts +21 -0
  24. package/dist/providers/auth0.js +80 -0
  25. package/dist/providers/authentik.d.ts +21 -0
  26. package/dist/providers/authentik.js +75 -0
  27. package/dist/providers/autodesk.d.ts +16 -0
  28. package/dist/providers/autodesk.js +60 -0
  29. package/dist/providers/battlenet.d.ts +16 -0
  30. package/dist/providers/battlenet.js +69 -0
  31. package/dist/providers/bitbucket.d.ts +15 -0
  32. package/dist/providers/bitbucket.js +79 -0
  33. package/dist/providers/box.d.ts +18 -0
  34. package/dist/providers/box.js +90 -0
  35. package/dist/providers/bungie.d.ts +17 -0
  36. package/dist/providers/bungie.js +72 -0
  37. package/dist/providers/coinbase.d.ts +18 -0
  38. package/dist/providers/coinbase.js +95 -0
  39. package/dist/providers/discord.d.ts +16 -0
  40. package/dist/providers/discord.js +68 -0
  41. package/dist/providers/donation-alerts.d.ts +17 -0
  42. package/dist/providers/donation-alerts.js +86 -0
  43. package/dist/providers/dribbble.d.ts +16 -0
  44. package/dist/providers/dribbble.js +73 -0
  45. package/dist/providers/dropbox.d.ts +16 -0
  46. package/dist/providers/dropbox.js +96 -0
  47. package/dist/providers/epicgames.d.ts +16 -0
  48. package/dist/providers/epicgames.js +60 -0
  49. package/dist/providers/etsy.d.ts +15 -0
  50. package/dist/providers/etsy.js +68 -0
  51. package/dist/providers/facebook.d.ts +16 -0
  52. package/dist/providers/facebook.js +80 -0
  53. package/dist/providers/figma.d.ts +15 -0
  54. package/dist/providers/figma.js +56 -0
  55. package/dist/providers/gitea.d.ts +19 -0
  56. package/dist/providers/gitea.js +62 -0
  57. package/dist/providers/github.d.ts +17 -0
  58. package/dist/providers/github.js +142 -0
  59. package/dist/providers/gitlab.d.ts +21 -0
  60. package/dist/providers/gitlab.js +64 -0
  61. package/dist/providers/google.d.ts +16 -0
  62. package/dist/providers/google.js +70 -0
  63. package/dist/providers/intuit.d.ts +16 -0
  64. package/dist/providers/intuit.js +66 -0
  65. package/dist/providers/kakao.d.ts +17 -0
  66. package/dist/providers/kakao.js +95 -0
  67. package/dist/providers/keycloak.d.ts +21 -0
  68. package/dist/providers/keycloak.js +74 -0
  69. package/dist/providers/kick.d.ts +18 -0
  70. package/dist/providers/kick.js +103 -0
  71. package/dist/providers/lichess.d.ts +14 -0
  72. package/dist/providers/lichess.js +63 -0
  73. package/dist/providers/line.d.ts +17 -0
  74. package/dist/providers/line.js +98 -0
  75. package/dist/providers/linear.d.ts +16 -0
  76. package/dist/providers/linear.js +112 -0
  77. package/dist/providers/linkedin.d.ts +17 -0
  78. package/dist/providers/linkedin.js +89 -0
  79. package/dist/providers/mastodon.d.ts +20 -0
  80. package/dist/providers/mastodon.js +67 -0
  81. package/dist/providers/mercadolibre.d.ts +17 -0
  82. package/dist/providers/mercadolibre.js +95 -0
  83. package/dist/providers/mercadopago.d.ts +17 -0
  84. package/dist/providers/mercadopago.js +95 -0
  85. package/dist/providers/microsoft-entra-id.d.ts +20 -0
  86. package/dist/providers/microsoft-entra-id.js +120 -0
  87. package/dist/providers/myanimelist.d.ts +15 -0
  88. package/dist/providers/myanimelist.js +56 -0
  89. package/dist/providers/naver.d.ts +17 -0
  90. package/dist/providers/naver.js +83 -0
  91. package/dist/providers/notion.d.ts +14 -0
  92. package/dist/providers/notion.js +65 -0
  93. package/dist/providers/okta.d.ts +22 -0
  94. package/dist/providers/okta.js +85 -0
  95. package/dist/providers/osu.d.ts +17 -0
  96. package/dist/providers/osu.js +82 -0
  97. package/dist/providers/patreon.d.ts +17 -0
  98. package/dist/providers/patreon.js +89 -0
  99. package/dist/providers/polar.d.ts +18 -0
  100. package/dist/providers/polar.js +100 -0
  101. package/dist/providers/reddit.d.ts +15 -0
  102. package/dist/providers/reddit.js +55 -0
  103. package/dist/providers/roblox.d.ts +16 -0
  104. package/dist/providers/roblox.js +67 -0
  105. package/dist/providers/salesforce.d.ts +21 -0
  106. package/dist/providers/salesforce.js +74 -0
  107. package/dist/providers/shikimori.d.ts +17 -0
  108. package/dist/providers/shikimori.js +81 -0
  109. package/dist/providers/slack.d.ts +14 -0
  110. package/dist/providers/slack.js +59 -0
  111. package/dist/providers/spotify.d.ts +15 -0
  112. package/dist/providers/spotify.js +67 -0
  113. package/dist/providers/startgg.d.ts +17 -0
  114. package/dist/providers/startgg.js +143 -0
  115. package/dist/providers/strava.d.ts +17 -0
  116. package/dist/providers/strava.js +85 -0
  117. package/dist/providers/synology.d.ts +9 -0
  118. package/dist/providers/synology.js +20 -0
  119. package/dist/providers/tiktok.d.ts +18 -0
  120. package/dist/providers/tiktok.js +109 -0
  121. package/dist/providers/tiltify.d.ts +17 -0
  122. package/dist/providers/tiltify.js +90 -0
  123. package/dist/providers/tumblr.d.ts +15 -0
  124. package/dist/providers/tumblr.js +63 -0
  125. package/dist/providers/twitch.d.ts +17 -0
  126. package/dist/providers/twitch.js +91 -0
  127. package/dist/providers/twitter.d.ts +16 -0
  128. package/dist/providers/twitter.js +67 -0
  129. package/dist/providers/vk.d.ts +16 -0
  130. package/dist/providers/vk.js +82 -0
  131. package/dist/providers/withings.d.ts +16 -0
  132. package/dist/providers/withings.js +120 -0
  133. package/dist/providers/workos.d.ts +16 -0
  134. package/dist/providers/workos.js +82 -0
  135. package/dist/providers/yahoo.d.ts +15 -0
  136. package/dist/providers/yahoo.js +65 -0
  137. package/dist/providers/yandex.d.ts +15 -0
  138. package/dist/providers/yandex.js +66 -0
  139. package/dist/providers/zoom.d.ts +16 -0
  140. package/dist/providers/zoom.js +66 -0
  141. package/dist/request.d.ts +26 -0
  142. package/dist/request.js +182 -0
  143. package/dist/utils.d.ts +2 -0
  144. package/dist/utils.js +20 -0
  145. package/package.json +42 -0
@@ -0,0 +1,70 @@
1
+ import { OAuth2Client, CodeChallengeMethod } from "../client.js";
2
+ import { decodeIdToken } from "../oidc.js";
3
+ import { consumeOAuthState, fetchUserProfile, generateOAuthCodeVerifier, generateOAuthState, InvalidOAuthCallbackError, parseCallbackQuery, profileId, profileString, requireAuthConfig, resolveAuthConfig, resolveScopes, saveOAuthState } from "../auth.js";
4
+ const authorizationEndpoint = "https://accounts.google.com/o/oauth2/v2/auth";
5
+ const tokenEndpoint = "https://oauth2.googleapis.com/token";
6
+ const tokenRevocationEndpoint = "https://oauth2.googleapis.com/revoke";
7
+ const userinfoEndpoint = "https://openidconnect.googleapis.com/v1/userinfo";
8
+ const envPrefix = "GOOGLE";
9
+ const defaultScopes = ["openid", "profile", "email"];
10
+ export class Google {
11
+ client;
12
+ auth = null;
13
+ constructor(clientIdOrOptions, clientSecret, redirectURI) {
14
+ if (typeof clientIdOrOptions === "object") {
15
+ this.auth = resolveAuthConfig(envPrefix, clientIdOrOptions, {
16
+ clientSecret: true,
17
+ redirectURI: true
18
+ });
19
+ this.client = new OAuth2Client(this.auth.clientId, this.auth.clientSecret, this.auth.redirectURI);
20
+ }
21
+ else {
22
+ this.client = new OAuth2Client(clientIdOrOptions, clientSecret ?? null, redirectURI ?? null);
23
+ }
24
+ }
25
+ createAuthorizationURL(state, codeVerifier, scopes) {
26
+ const url = this.client.createAuthorizationURLWithPKCE(authorizationEndpoint, state, CodeChallengeMethod.S256, codeVerifier, scopes);
27
+ return url;
28
+ }
29
+ async validateAuthorizationCode(code, codeVerifier) {
30
+ const tokens = await this.client.validateAuthorizationCode(tokenEndpoint, code, codeVerifier);
31
+ return tokens;
32
+ }
33
+ async refreshAccessToken(refreshToken) {
34
+ const tokens = await this.client.refreshAccessToken(tokenEndpoint, refreshToken, []);
35
+ return tokens;
36
+ }
37
+ async revokeToken(token) {
38
+ await this.client.revokeToken(tokenRevocationEndpoint, token);
39
+ }
40
+ async getAuthorizationURL(scopes) {
41
+ const auth = requireAuthConfig(this.auth);
42
+ const state = generateOAuthState();
43
+ const codeVerifier = generateOAuthCodeVerifier();
44
+ const url = this.createAuthorizationURL(state, codeVerifier, resolveScopes(scopes, auth, defaultScopes));
45
+ await saveOAuthState(auth.store, state, { codeVerifier });
46
+ return url;
47
+ }
48
+ async getUser(query) {
49
+ const auth = requireAuthConfig(this.auth);
50
+ const { code, state } = parseCallbackQuery(query);
51
+ const stored = await consumeOAuthState(auth.store, state);
52
+ if (typeof stored.codeVerifier !== "string") {
53
+ throw new InvalidOAuthCallbackError("Missing PKCE code verifier for OAuth state");
54
+ }
55
+ const tokens = await this.validateAuthorizationCode(code, stored.codeVerifier);
56
+ let claims;
57
+ if ("id_token" in tokens.data) {
58
+ claims = decodeIdToken(tokens.idToken());
59
+ }
60
+ else {
61
+ claims = await fetchUserProfile(userinfoEndpoint, tokens.accessToken());
62
+ }
63
+ return {
64
+ id: profileId(claims.sub),
65
+ name: profileString(claims.name),
66
+ email: profileString(claims.email),
67
+ image: profileString(claims.picture)
68
+ };
69
+ }
70
+ }
@@ -0,0 +1,16 @@
1
+ import type { OAuth2Tokens } from "../oauth2.js";
2
+ import type { OAuthCallbackQuery, OAuthUser, ProviderOptions } from "../auth.js";
3
+ export interface IntuitOptions extends ProviderOptions {
4
+ }
5
+ export declare class Intuit {
6
+ private client;
7
+ private auth;
8
+ constructor(options: IntuitOptions);
9
+ constructor(clientId: string, clientSecret: string, redirectURI: string);
10
+ createAuthorizationURL(state: string, scopes: string[]): URL;
11
+ validateAuthorizationCode(code: string): Promise<OAuth2Tokens>;
12
+ refreshAccessToken(refreshToken: string): Promise<OAuth2Tokens>;
13
+ revokeToken(token: string): Promise<void>;
14
+ getAuthorizationURL(scopes?: string[]): Promise<URL>;
15
+ getUser(query: OAuthCallbackQuery): Promise<OAuthUser>;
16
+ }
@@ -0,0 +1,66 @@
1
+ import { OAuth2Client } from "../client.js";
2
+ import { consumeOAuthState, fetchUserProfile, generateOAuthState, parseCallbackQuery, profileId, profileString, requireAuthConfig, resolveAuthConfig, resolveScopes, saveOAuthState } from "../auth.js";
3
+ const authorizationEndpoint = "https://appcenter.intuit.com/connect/oauth2";
4
+ const tokenEndpoint = "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer";
5
+ const tokenRevocationEndpoint = "https://developer.API.intuit.com/v2/oauth2/tokens/revoke";
6
+ const userinfoEndpoint = "https://accounts.platform.intuit.com/v1/openid_connect/userinfo";
7
+ const envPrefix = "INTUIT";
8
+ const defaultScopes = ["openid", "profile", "email"];
9
+ export class Intuit {
10
+ client;
11
+ auth = null;
12
+ constructor(clientIdOrOptions, clientSecret, redirectURI) {
13
+ if (typeof clientIdOrOptions === "object") {
14
+ this.auth = resolveAuthConfig(envPrefix, clientIdOrOptions, {
15
+ clientSecret: true,
16
+ redirectURI: true
17
+ });
18
+ this.client = new OAuth2Client(this.auth.clientId, this.auth.clientSecret, this.auth.redirectURI);
19
+ }
20
+ else {
21
+ this.client = new OAuth2Client(clientIdOrOptions, clientSecret ?? null, redirectURI ?? null);
22
+ }
23
+ }
24
+ createAuthorizationURL(state, scopes) {
25
+ const url = this.client.createAuthorizationURL(authorizationEndpoint, state, scopes);
26
+ return url;
27
+ }
28
+ async validateAuthorizationCode(code) {
29
+ const tokens = await this.client.validateAuthorizationCode(tokenEndpoint, code, null);
30
+ return tokens;
31
+ }
32
+ async refreshAccessToken(refreshToken) {
33
+ const tokens = await this.client.refreshAccessToken(tokenEndpoint, refreshToken, []);
34
+ return tokens;
35
+ }
36
+ async revokeToken(token) {
37
+ await this.client.revokeToken(tokenRevocationEndpoint, token);
38
+ }
39
+ async getAuthorizationURL(scopes) {
40
+ const auth = requireAuthConfig(this.auth);
41
+ const state = generateOAuthState();
42
+ const url = this.createAuthorizationURL(state, resolveScopes(scopes, auth, defaultScopes));
43
+ await saveOAuthState(auth.store, state, {});
44
+ return url;
45
+ }
46
+ async getUser(query) {
47
+ const auth = requireAuthConfig(this.auth);
48
+ const { code, state } = parseCallbackQuery(query);
49
+ await consumeOAuthState(auth.store, state);
50
+ const tokens = await this.validateAuthorizationCode(code);
51
+ // Intuit id_tokens omit profile claims, so always use the OIDC userinfo endpoint.
52
+ const claims = await fetchUserProfile(userinfoEndpoint, tokens.accessToken());
53
+ const givenName = profileString(claims.givenName);
54
+ const familyName = profileString(claims.familyName);
55
+ let name = null;
56
+ if (givenName !== null || familyName !== null) {
57
+ name = [givenName, familyName].filter((part) => part !== null).join(" ");
58
+ }
59
+ return {
60
+ id: profileId(claims.sub),
61
+ name,
62
+ email: profileString(claims.email),
63
+ image: null
64
+ };
65
+ }
66
+ }
@@ -0,0 +1,17 @@
1
+ import type { OAuth2Tokens } from "../oauth2.js";
2
+ import type { OAuthCallbackQuery, OAuthUser, ProviderOptions } from "../auth.js";
3
+ export interface KakaoOptions extends ProviderOptions {
4
+ }
5
+ export declare class Kakao {
6
+ private clientId;
7
+ private clientSecret;
8
+ private redirectURI;
9
+ private auth;
10
+ constructor(options: KakaoOptions);
11
+ constructor(clientId: string, clientSecret: string, redirectURI: string);
12
+ createAuthorizationURL(state: string, scopes: string[]): URL;
13
+ validateAuthorizationCode(code: string): Promise<OAuth2Tokens>;
14
+ refreshAccessToken(refreshToken: string): Promise<OAuth2Tokens>;
15
+ getAuthorizationURL(scopes?: string[]): Promise<URL>;
16
+ getUser(query: OAuthCallbackQuery): Promise<OAuthUser>;
17
+ }
@@ -0,0 +1,95 @@
1
+ import { createOAuth2Request, sendTokenRequest } from "../request.js";
2
+ import { consumeOAuthState, fetchUserProfile, generateOAuthState, parseCallbackQuery, profileId, profileString, requireAuthConfig, resolveAuthConfig, resolveScopes, saveOAuthState } from "../auth.js";
3
+ const authorizationEndpoint = "https://kauth.kakao.com/oauth/authorize";
4
+ const tokenEndpoint = "https://kauth.kakao.com/oauth/token";
5
+ const userEndpoint = "https://kapi.kakao.com/v2/user/me";
6
+ const envPrefix = "KAKAO";
7
+ const defaultScopes = ["profile_nickname", "profile_image", "account_email"];
8
+ export class Kakao {
9
+ clientId;
10
+ clientSecret;
11
+ redirectURI;
12
+ auth = null;
13
+ constructor(clientIdOrOptions, clientSecret, redirectURI) {
14
+ if (typeof clientIdOrOptions === "object") {
15
+ this.auth = resolveAuthConfig(envPrefix, clientIdOrOptions, {
16
+ clientSecret: true,
17
+ redirectURI: true
18
+ });
19
+ this.clientId = this.auth.clientId;
20
+ this.clientSecret = this.auth.clientSecret ?? "";
21
+ this.redirectURI = this.auth.redirectURI ?? "";
22
+ }
23
+ else {
24
+ this.clientId = clientIdOrOptions;
25
+ this.clientSecret = clientSecret ?? "";
26
+ this.redirectURI = redirectURI ?? "";
27
+ }
28
+ }
29
+ createAuthorizationURL(state, scopes) {
30
+ const url = new URL(authorizationEndpoint);
31
+ url.searchParams.set("response_type", "code");
32
+ url.searchParams.set("client_id", this.clientId);
33
+ url.searchParams.set("state", state);
34
+ if (scopes.length > 0) {
35
+ url.searchParams.set("scope", scopes.join(" "));
36
+ }
37
+ url.searchParams.set("redirect_uri", this.redirectURI);
38
+ return url;
39
+ }
40
+ async validateAuthorizationCode(code) {
41
+ const body = new URLSearchParams();
42
+ body.set("grant_type", "authorization_code");
43
+ body.set("code", code);
44
+ body.set("redirect_uri", this.redirectURI);
45
+ body.set("client_id", this.clientId);
46
+ body.set("client_secret", this.clientSecret);
47
+ const request = createOAuth2Request(tokenEndpoint, body);
48
+ const tokens = await sendTokenRequest(request);
49
+ return tokens;
50
+ }
51
+ async refreshAccessToken(refreshToken) {
52
+ const body = new URLSearchParams();
53
+ body.set("grant_type", "refresh_token");
54
+ body.set("refresh_token", refreshToken);
55
+ body.set("client_id", this.clientId);
56
+ body.set("client_secret", this.clientSecret);
57
+ const request = createOAuth2Request(tokenEndpoint, body);
58
+ const tokens = await sendTokenRequest(request);
59
+ return tokens;
60
+ }
61
+ async getAuthorizationURL(scopes) {
62
+ const auth = requireAuthConfig(this.auth);
63
+ const state = generateOAuthState();
64
+ const url = this.createAuthorizationURL(state, resolveScopes(scopes, auth, defaultScopes));
65
+ await saveOAuthState(auth.store, state, {});
66
+ return url;
67
+ }
68
+ async getUser(query) {
69
+ const auth = requireAuthConfig(this.auth);
70
+ const { code, state } = parseCallbackQuery(query);
71
+ await consumeOAuthState(auth.store, state);
72
+ const tokens = await this.validateAuthorizationCode(code);
73
+ const profile = await fetchUserProfile(userEndpoint, tokens.accessToken());
74
+ let name = null;
75
+ let email = null;
76
+ let image = null;
77
+ const account = profile.kakao_account;
78
+ if (typeof account === "object" && account !== null) {
79
+ const accountRecord = account;
80
+ email = profileString(accountRecord.email);
81
+ const kakaoProfile = accountRecord.profile;
82
+ if (typeof kakaoProfile === "object" && kakaoProfile !== null) {
83
+ const profileRecord = kakaoProfile;
84
+ name = profileString(profileRecord.nickname);
85
+ image = profileString(profileRecord.profile_image_url);
86
+ }
87
+ }
88
+ return {
89
+ id: profileId(profile.id),
90
+ name,
91
+ email,
92
+ image
93
+ };
94
+ }
95
+ }
@@ -0,0 +1,21 @@
1
+ import type { OAuth2Tokens } from "../oauth2.js";
2
+ import type { OAuthCallbackQuery, OAuthUser, ProviderOptions } from "../auth.js";
3
+ export interface KeyCloakOptions extends ProviderOptions {
4
+ realmURL?: string;
5
+ }
6
+ export declare class KeyCloak {
7
+ private authorizationEndpoint;
8
+ private tokenEndpoint;
9
+ private tokenRevocationEndpoint;
10
+ private userinfoEndpoint;
11
+ private client;
12
+ private auth;
13
+ constructor(options: KeyCloakOptions);
14
+ constructor(realmURL: string, clientId: string, clientSecret: string | null, redirectURI: string);
15
+ createAuthorizationURL(state: string, codeVerifier: string, scopes: string[]): URL;
16
+ validateAuthorizationCode(code: string, codeVerifier: string): Promise<OAuth2Tokens>;
17
+ refreshAccessToken(refreshToken: string): Promise<OAuth2Tokens>;
18
+ revokeToken(token: string): Promise<void>;
19
+ getAuthorizationURL(scopes?: string[]): Promise<URL>;
20
+ getUser(query: OAuthCallbackQuery): Promise<OAuthUser>;
21
+ }
@@ -0,0 +1,74 @@
1
+ import { CodeChallengeMethod, OAuth2Client } from "../client.js";
2
+ import { decodeIdToken } from "../oidc.js";
3
+ import { consumeOAuthState, fetchUserProfile, generateOAuthCodeVerifier, generateOAuthState, InvalidOAuthCallbackError, parseCallbackQuery, profileId, profileString, requireAuthConfig, requireProviderOption, resolveAuthConfig, resolveScopes, saveOAuthState } from "../auth.js";
4
+ const envPrefix = "KEYCLOAK";
5
+ const defaultScopes = ["openid", "profile", "email"];
6
+ export class KeyCloak {
7
+ authorizationEndpoint;
8
+ tokenEndpoint;
9
+ tokenRevocationEndpoint;
10
+ userinfoEndpoint;
11
+ client;
12
+ auth = null;
13
+ constructor(realmURLOrOptions, clientId, clientSecret, redirectURI) {
14
+ let realmURL;
15
+ if (typeof realmURLOrOptions === "object") {
16
+ this.auth = resolveAuthConfig(envPrefix, realmURLOrOptions, { redirectURI: true });
17
+ realmURL = requireProviderOption(realmURLOrOptions.realmURL, envPrefix, "REALM_URL", "realmURL");
18
+ this.client = new OAuth2Client(this.auth.clientId, this.auth.clientSecret, this.auth.redirectURI);
19
+ }
20
+ else {
21
+ realmURL = realmURLOrOptions;
22
+ this.client = new OAuth2Client(clientId ?? "", clientSecret ?? null, redirectURI ?? null);
23
+ }
24
+ this.authorizationEndpoint = realmURL + "/protocol/openid-connect/auth";
25
+ this.tokenEndpoint = realmURL + "/protocol/openid-connect/token";
26
+ this.tokenRevocationEndpoint = realmURL + "/protocol/openid-connect/revoke";
27
+ this.userinfoEndpoint = realmURL + "/protocol/openid-connect/userinfo";
28
+ }
29
+ createAuthorizationURL(state, codeVerifier, scopes) {
30
+ const url = this.client.createAuthorizationURLWithPKCE(this.authorizationEndpoint, state, CodeChallengeMethod.S256, codeVerifier, scopes);
31
+ return url;
32
+ }
33
+ async validateAuthorizationCode(code, codeVerifier) {
34
+ const tokens = await this.client.validateAuthorizationCode(this.tokenEndpoint, code, codeVerifier);
35
+ return tokens;
36
+ }
37
+ async refreshAccessToken(refreshToken) {
38
+ const tokens = await this.client.refreshAccessToken(this.tokenEndpoint, refreshToken, []);
39
+ return tokens;
40
+ }
41
+ async revokeToken(token) {
42
+ await this.client.revokeToken(this.tokenRevocationEndpoint, token);
43
+ }
44
+ async getAuthorizationURL(scopes) {
45
+ const auth = requireAuthConfig(this.auth);
46
+ const state = generateOAuthState();
47
+ const codeVerifier = generateOAuthCodeVerifier();
48
+ const url = this.createAuthorizationURL(state, codeVerifier, resolveScopes(scopes, auth, defaultScopes));
49
+ await saveOAuthState(auth.store, state, { codeVerifier });
50
+ return url;
51
+ }
52
+ async getUser(query) {
53
+ const auth = requireAuthConfig(this.auth);
54
+ const { code, state } = parseCallbackQuery(query);
55
+ const stored = await consumeOAuthState(auth.store, state);
56
+ if (typeof stored.codeVerifier !== "string") {
57
+ throw new InvalidOAuthCallbackError("Missing PKCE code verifier for OAuth state");
58
+ }
59
+ const tokens = await this.validateAuthorizationCode(code, stored.codeVerifier);
60
+ let claims;
61
+ if ("id_token" in tokens.data) {
62
+ claims = decodeIdToken(tokens.idToken());
63
+ }
64
+ else {
65
+ claims = await fetchUserProfile(this.userinfoEndpoint, tokens.accessToken());
66
+ }
67
+ return {
68
+ id: profileId(claims.sub),
69
+ name: profileString(claims.name) ?? profileString(claims.preferred_username),
70
+ email: profileString(claims.email),
71
+ image: profileString(claims.picture)
72
+ };
73
+ }
74
+ }
@@ -0,0 +1,18 @@
1
+ import { type OAuth2Tokens } from "../oauth2.js";
2
+ import type { OAuthCallbackQuery, OAuthUser, ProviderOptions } from "../auth.js";
3
+ export interface KickOptions extends ProviderOptions {
4
+ }
5
+ export declare class Kick {
6
+ private clientId;
7
+ private clientSecret;
8
+ private redirectURI;
9
+ private auth;
10
+ constructor(options: KickOptions);
11
+ constructor(clientId: string, clientSecret: string, redirectURI: string);
12
+ createAuthorizationURL(state: string, codeVerifier: string, scopes: string[]): URL;
13
+ validateAuthorizationCode(code: string, codeVerifier: string): Promise<OAuth2Tokens>;
14
+ refreshAccessToken(refreshToken: string): Promise<OAuth2Tokens>;
15
+ revokeToken(token: string): Promise<void>;
16
+ getAuthorizationURL(scopes?: string[]): Promise<URL>;
17
+ getUser(query: OAuthCallbackQuery): Promise<OAuthUser>;
18
+ }
@@ -0,0 +1,103 @@
1
+ import { createOAuth2Request, sendTokenRequest, sendTokenRevocationRequest } from "../request.js";
2
+ import { createS256CodeChallenge } from "../oauth2.js";
3
+ import { consumeOAuthState, fetchUserProfile, generateOAuthCodeVerifier, generateOAuthState, InvalidOAuthCallbackError, OAuthProviderError, parseCallbackQuery, profileId, profileString, requireAuthConfig, resolveAuthConfig, resolveScopes, saveOAuthState } from "../auth.js";
4
+ const authorizationEndpoint = "https://id.kick.com/oauth/authorize";
5
+ const tokenEndpoint = "https://id.kick.com/oauth/token";
6
+ const tokenRevocationEndpoint = "https://id.kick.com/oauth/revoke";
7
+ const userEndpoint = "https://api.kick.com/public/v1/users";
8
+ const envPrefix = "KICK";
9
+ const defaultScopes = ["user:read"];
10
+ export class Kick {
11
+ clientId;
12
+ clientSecret;
13
+ redirectURI;
14
+ auth = null;
15
+ constructor(clientIdOrOptions, clientSecret, redirectURI) {
16
+ if (typeof clientIdOrOptions === "object") {
17
+ this.auth = resolveAuthConfig(envPrefix, clientIdOrOptions, {
18
+ clientSecret: true,
19
+ redirectURI: true
20
+ });
21
+ this.clientId = this.auth.clientId;
22
+ this.clientSecret = this.auth.clientSecret ?? "";
23
+ this.redirectURI = this.auth.redirectURI ?? "";
24
+ }
25
+ else {
26
+ this.clientId = clientIdOrOptions;
27
+ this.clientSecret = clientSecret ?? "";
28
+ this.redirectURI = redirectURI ?? "";
29
+ }
30
+ }
31
+ createAuthorizationURL(state, codeVerifier, scopes) {
32
+ const url = new URL(authorizationEndpoint);
33
+ url.searchParams.set("client_id", this.clientId);
34
+ url.searchParams.set("response_type", "code");
35
+ url.searchParams.set("redirect_uri", this.redirectURI);
36
+ url.searchParams.set("state", state);
37
+ if (scopes.length > 0) {
38
+ url.searchParams.set("scope", scopes.join(" "));
39
+ }
40
+ const codeChallenge = createS256CodeChallenge(codeVerifier);
41
+ url.searchParams.set("code_challenge", codeChallenge);
42
+ url.searchParams.set("code_challenge_method", "S256");
43
+ return url;
44
+ }
45
+ async validateAuthorizationCode(code, codeVerifier) {
46
+ const body = new URLSearchParams();
47
+ body.set("code", code);
48
+ body.set("client_id", this.clientId);
49
+ body.set("client_secret", this.clientSecret);
50
+ body.set("redirect_uri", this.redirectURI);
51
+ body.set("grant_type", "authorization_code");
52
+ body.set("code_verifier", codeVerifier);
53
+ const request = createOAuth2Request(tokenEndpoint, body);
54
+ const tokens = await sendTokenRequest(request);
55
+ return tokens;
56
+ }
57
+ async refreshAccessToken(refreshToken) {
58
+ const body = new URLSearchParams();
59
+ body.set("refresh_token", refreshToken);
60
+ body.set("client_id", this.clientId);
61
+ body.set("client_secret", this.clientSecret);
62
+ body.set("grant_type", "refresh_token");
63
+ const request = createOAuth2Request(tokenEndpoint, body);
64
+ const tokens = await sendTokenRequest(request);
65
+ return tokens;
66
+ }
67
+ async revokeToken(token) {
68
+ const body = new URLSearchParams();
69
+ body.set("token", token);
70
+ const request = createOAuth2Request(tokenRevocationEndpoint, body);
71
+ await sendTokenRevocationRequest(request);
72
+ }
73
+ async getAuthorizationURL(scopes) {
74
+ const auth = requireAuthConfig(this.auth);
75
+ const state = generateOAuthState();
76
+ const codeVerifier = generateOAuthCodeVerifier();
77
+ const url = this.createAuthorizationURL(state, codeVerifier, resolveScopes(scopes, auth, defaultScopes));
78
+ await saveOAuthState(auth.store, state, { codeVerifier });
79
+ return url;
80
+ }
81
+ async getUser(query) {
82
+ const auth = requireAuthConfig(this.auth);
83
+ const { code, state } = parseCallbackQuery(query);
84
+ const stored = await consumeOAuthState(auth.store, state);
85
+ if (typeof stored.codeVerifier !== "string") {
86
+ throw new InvalidOAuthCallbackError("Missing PKCE code verifier for OAuth state");
87
+ }
88
+ const tokens = await this.validateAuthorizationCode(code, stored.codeVerifier);
89
+ // Without user IDs the endpoint returns the authorized user as the only data entry.
90
+ const response = await fetchUserProfile(userEndpoint, tokens.accessToken());
91
+ const entries = response.data;
92
+ if (!Array.isArray(entries) || typeof entries[0] !== "object" || entries[0] === null) {
93
+ throw new OAuthProviderError("Unexpected user profile response body");
94
+ }
95
+ const profile = entries[0];
96
+ return {
97
+ id: profileId(profile.user_id),
98
+ name: profileString(profile.name),
99
+ email: profileString(profile.email),
100
+ image: profileString(profile.profile_picture)
101
+ };
102
+ }
103
+ }
@@ -0,0 +1,14 @@
1
+ import type { OAuth2Tokens } from "../oauth2.js";
2
+ import type { OAuthCallbackQuery, OAuthUser, ProviderOptions } from "../auth.js";
3
+ export interface LichessOptions extends ProviderOptions {
4
+ }
5
+ export declare class Lichess {
6
+ private client;
7
+ private auth;
8
+ constructor(options: LichessOptions);
9
+ constructor(clientId: string, redirectURI: string);
10
+ createAuthorizationURL(state: string, codeVerifier: string, scopes: string[]): URL;
11
+ validateAuthorizationCode(code: string, codeVerifier: string): Promise<OAuth2Tokens>;
12
+ getAuthorizationURL(scopes?: string[]): Promise<URL>;
13
+ getUser(query: OAuthCallbackQuery): Promise<OAuthUser>;
14
+ }
@@ -0,0 +1,63 @@
1
+ import { OAuth2Client, CodeChallengeMethod } from "../client.js";
2
+ import { consumeOAuthState, fetchUserProfile, generateOAuthCodeVerifier, generateOAuthState, InvalidOAuthCallbackError, parseCallbackQuery, profileId, profileString, requireAuthConfig, resolveAuthConfig, resolveScopes, saveOAuthState } from "../auth.js";
3
+ const authorizationEndpoint = "https://lichess.org/oauth";
4
+ const tokenEndpoint = "https://lichess.org/api/token";
5
+ const accountEndpoint = "https://lichess.org/api/account";
6
+ const accountEmailEndpoint = "https://lichess.org/api/account/email";
7
+ const envPrefix = "LICHESS";
8
+ const defaultScopes = ["email:read"];
9
+ export class Lichess {
10
+ client;
11
+ auth = null;
12
+ constructor(clientIdOrOptions, redirectURI) {
13
+ if (typeof clientIdOrOptions === "object") {
14
+ this.auth = resolveAuthConfig(envPrefix, clientIdOrOptions, { redirectURI: true });
15
+ this.client = new OAuth2Client(this.auth.clientId, null, this.auth.redirectURI);
16
+ }
17
+ else {
18
+ this.client = new OAuth2Client(clientIdOrOptions, null, redirectURI ?? null);
19
+ }
20
+ }
21
+ createAuthorizationURL(state, codeVerifier, scopes) {
22
+ const url = this.client.createAuthorizationURLWithPKCE(authorizationEndpoint, state, CodeChallengeMethod.S256, codeVerifier, scopes);
23
+ return url;
24
+ }
25
+ async validateAuthorizationCode(code, codeVerifier) {
26
+ const tokens = await this.client.validateAuthorizationCode(tokenEndpoint, code, codeVerifier);
27
+ return tokens;
28
+ }
29
+ async getAuthorizationURL(scopes) {
30
+ const auth = requireAuthConfig(this.auth);
31
+ const state = generateOAuthState();
32
+ const codeVerifier = generateOAuthCodeVerifier();
33
+ const url = this.createAuthorizationURL(state, codeVerifier, resolveScopes(scopes, auth, defaultScopes));
34
+ await saveOAuthState(auth.store, state, { codeVerifier });
35
+ return url;
36
+ }
37
+ async getUser(query) {
38
+ const auth = requireAuthConfig(this.auth);
39
+ const { code, state } = parseCallbackQuery(query);
40
+ const stored = await consumeOAuthState(auth.store, state);
41
+ if (typeof stored.codeVerifier !== "string") {
42
+ throw new InvalidOAuthCallbackError("Missing PKCE code verifier for OAuth state");
43
+ }
44
+ const tokens = await this.validateAuthorizationCode(code, stored.codeVerifier);
45
+ const accessToken = tokens.accessToken();
46
+ const profile = await fetchUserProfile(accountEndpoint, accessToken);
47
+ // Requires the email:read scope, so tolerate failure.
48
+ let email = null;
49
+ try {
50
+ const response = await fetchUserProfile(accountEmailEndpoint, accessToken);
51
+ email = profileString(response.email);
52
+ }
53
+ catch {
54
+ email = null;
55
+ }
56
+ return {
57
+ id: profileId(profile.id),
58
+ name: profileString(profile.username),
59
+ email,
60
+ image: null
61
+ };
62
+ }
63
+ }
@@ -0,0 +1,17 @@
1
+ import type { OAuth2Tokens } from "../oauth2.js";
2
+ import type { OAuthCallbackQuery, OAuthUser, ProviderOptions } from "../auth.js";
3
+ export interface LineOptions extends ProviderOptions {
4
+ }
5
+ export declare class Line {
6
+ private clientId;
7
+ private clientSecret;
8
+ private redirectURI;
9
+ private auth;
10
+ constructor(options: LineOptions);
11
+ constructor(clientId: string, clientSecret: string, redirectURI: string);
12
+ createAuthorizationURL(state: string, codeVerifier: string, scopes: string[]): URL;
13
+ validateAuthorizationCode(code: string, codeVerifier: string): Promise<OAuth2Tokens>;
14
+ refreshAccessToken(refreshToken: string): Promise<OAuth2Tokens>;
15
+ getAuthorizationURL(scopes?: string[]): Promise<URL>;
16
+ getUser(query: OAuthCallbackQuery): Promise<OAuthUser>;
17
+ }