@shadowob/oauth 1.1.6 → 1.1.8

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.
package/dist/index.cjs CHANGED
@@ -20,10 +20,75 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- ShadowOAuth: () => ShadowOAuth
23
+ SHADOW_OAUTH_AUTHORIZE_PATHS: () => SHADOW_OAUTH_AUTHORIZE_PATHS,
24
+ SHADOW_OAUTH_SCOPE_GROUPS: () => SHADOW_OAUTH_SCOPE_GROUPS,
25
+ ShadowOAuth: () => ShadowOAuth,
26
+ buildShadowOAuthDenyRedirect: () => buildShadowOAuthDenyRedirect,
27
+ parseShadowOAuthAuthorizeUrl: () => parseShadowOAuthAuthorizeUrl,
28
+ shadowOAuthAuthorizeApiPath: () => shadowOAuthAuthorizeApiPath
24
29
  });
25
30
  module.exports = __toCommonJS(index_exports);
26
31
 
32
+ // src/authorization.ts
33
+ var SHADOW_OAUTH_AUTHORIZE_PATHS = ["/app/oauth/authorize", "/oauth/authorize"];
34
+ var SHADOW_OAUTH_SCOPE_GROUPS = [
35
+ { key: "user", scopes: ["user:read", "user:email"] },
36
+ { key: "servers", scopes: ["servers:read", "servers:write"] },
37
+ { key: "channels", scopes: ["channels:read", "channels:write"] },
38
+ { key: "messages", scopes: ["messages:read", "messages:write"] },
39
+ { key: "attachments", scopes: ["attachments:read", "attachments:write"] },
40
+ { key: "workspaces", scopes: ["workspaces:read", "workspaces:write"] },
41
+ { key: "buddies", scopes: ["buddies:create", "buddies:manage"] },
42
+ { key: "commerce", scopes: ["commerce:read", "commerce:write"] }
43
+ ];
44
+ function originFor(value) {
45
+ try {
46
+ return new URL(value).origin;
47
+ } catch {
48
+ return null;
49
+ }
50
+ }
51
+ function parseShadowOAuthAuthorizeUrl(input, options = {}) {
52
+ let url;
53
+ try {
54
+ url = new URL(input);
55
+ } catch {
56
+ return null;
57
+ }
58
+ const allowedOrigins = options.allowedOrigins?.map(originFor).filter((origin) => Boolean(origin));
59
+ if (allowedOrigins?.length && !allowedOrigins.includes(url.origin)) return null;
60
+ const authorizePathnames = options.authorizePathnames ?? [...SHADOW_OAUTH_AUTHORIZE_PATHS];
61
+ if (!authorizePathnames.includes(url.pathname)) return null;
62
+ const responseType = url.searchParams.get("response_type") ?? "code";
63
+ const clientId = url.searchParams.get("client_id")?.trim();
64
+ const redirectUri = url.searchParams.get("redirect_uri")?.trim();
65
+ if (responseType !== "code" || !clientId || !redirectUri) return null;
66
+ return {
67
+ responseType: "code",
68
+ clientId,
69
+ redirectUri,
70
+ scope: url.searchParams.get("scope")?.trim() || "user:read",
71
+ state: url.searchParams.get("state") ?? void 0,
72
+ sourceUrl: url.toString()
73
+ };
74
+ }
75
+ function shadowOAuthAuthorizeApiPath(request) {
76
+ const params = new URLSearchParams({
77
+ response_type: request.responseType,
78
+ client_id: request.clientId,
79
+ redirect_uri: request.redirectUri,
80
+ scope: request.scope
81
+ });
82
+ if (request.state) params.set("state", request.state);
83
+ return `/api/oauth/authorize?${params.toString()}`;
84
+ }
85
+ function buildShadowOAuthDenyRedirect(request, error = "access_denied") {
86
+ const url = new URL(request.redirectUri);
87
+ url.searchParams.set("error", error);
88
+ if (request.state) url.searchParams.set("state", request.state);
89
+ return url.toString();
90
+ }
91
+
27
92
  // src/client.ts
28
93
  var DEFAULT_BASE_URL = "https://shadowob.com";
29
94
  var ShadowOAuth = class {
@@ -51,7 +116,7 @@ var ShadowOAuth = class {
51
116
  if (options?.state) {
52
117
  params.set("state", options.state);
53
118
  }
54
- return `${this.baseUrl}/oauth/authorize?${params.toString()}`;
119
+ return `${this.baseUrl}/app/oauth/authorize?${params.toString()}`;
55
120
  }
56
121
  /**
57
122
  * Exchange an authorization code for access and refresh tokens.
@@ -263,5 +328,10 @@ var ShadowOAuth = class {
263
328
  };
264
329
  // Annotate the CommonJS export names for ESM import in node:
265
330
  0 && (module.exports = {
266
- ShadowOAuth
331
+ SHADOW_OAUTH_AUTHORIZE_PATHS,
332
+ SHADOW_OAUTH_SCOPE_GROUPS,
333
+ ShadowOAuth,
334
+ buildShadowOAuthDenyRedirect,
335
+ parseShadowOAuthAuthorizeUrl,
336
+ shadowOAuthAuthorizeApiPath
267
337
  });
package/dist/index.d.cts CHANGED
@@ -1,3 +1,45 @@
1
+ interface ShadowOAuthAuthorizationRequest {
2
+ responseType: 'code';
3
+ clientId: string;
4
+ redirectUri: string;
5
+ scope: string;
6
+ state?: string;
7
+ sourceUrl: string;
8
+ }
9
+ interface ShadowOAuthAuthorizeUrlOptions {
10
+ allowedOrigins?: string[];
11
+ authorizePathnames?: string[];
12
+ }
13
+ declare const SHADOW_OAUTH_AUTHORIZE_PATHS: readonly ["/app/oauth/authorize", "/oauth/authorize"];
14
+ declare const SHADOW_OAUTH_SCOPE_GROUPS: readonly [{
15
+ readonly key: "user";
16
+ readonly scopes: readonly ["user:read", "user:email"];
17
+ }, {
18
+ readonly key: "servers";
19
+ readonly scopes: readonly ["servers:read", "servers:write"];
20
+ }, {
21
+ readonly key: "channels";
22
+ readonly scopes: readonly ["channels:read", "channels:write"];
23
+ }, {
24
+ readonly key: "messages";
25
+ readonly scopes: readonly ["messages:read", "messages:write"];
26
+ }, {
27
+ readonly key: "attachments";
28
+ readonly scopes: readonly ["attachments:read", "attachments:write"];
29
+ }, {
30
+ readonly key: "workspaces";
31
+ readonly scopes: readonly ["workspaces:read", "workspaces:write"];
32
+ }, {
33
+ readonly key: "buddies";
34
+ readonly scopes: readonly ["buddies:create", "buddies:manage"];
35
+ }, {
36
+ readonly key: "commerce";
37
+ readonly scopes: readonly ["commerce:read", "commerce:write"];
38
+ }];
39
+ declare function parseShadowOAuthAuthorizeUrl(input: string, options?: ShadowOAuthAuthorizeUrlOptions): ShadowOAuthAuthorizationRequest | null;
40
+ declare function shadowOAuthAuthorizeApiPath(request: ShadowOAuthAuthorizationRequest): string;
41
+ declare function buildShadowOAuthDenyRedirect(request: Pick<ShadowOAuthAuthorizationRequest, 'redirectUri' | 'state'>, error?: string): string;
42
+
1
43
  interface ShadowOAuthConfig {
2
44
  /** Your app's client_id from Shadow Developer Portal */
3
45
  clientId: string;
@@ -238,4 +280,4 @@ declare class ShadowOAuth {
238
280
  private oauthPost;
239
281
  }
240
282
 
241
- export { ShadowOAuth, type ShadowOAuthBuddy, type ShadowOAuthChannel, type ShadowOAuthCommerceEntitlementAccess, type ShadowOAuthCommerceEntitlementRedeemInput, type ShadowOAuthCommerceEntitlementRedeemResult, type ShadowOAuthCommerceEntitlementRedemption, type ShadowOAuthCommerceEntitlementSummary, type ShadowOAuthConfig, type ShadowOAuthMessage, type ShadowOAuthScope, type ShadowOAuthServer, type ShadowOAuthTokens, type ShadowOAuthUser, type ShadowOAuthWorkspace };
283
+ export { SHADOW_OAUTH_AUTHORIZE_PATHS, SHADOW_OAUTH_SCOPE_GROUPS, ShadowOAuth, type ShadowOAuthAuthorizationRequest, type ShadowOAuthAuthorizeUrlOptions, type ShadowOAuthBuddy, type ShadowOAuthChannel, type ShadowOAuthCommerceEntitlementAccess, type ShadowOAuthCommerceEntitlementRedeemInput, type ShadowOAuthCommerceEntitlementRedeemResult, type ShadowOAuthCommerceEntitlementRedemption, type ShadowOAuthCommerceEntitlementSummary, type ShadowOAuthConfig, type ShadowOAuthMessage, type ShadowOAuthScope, type ShadowOAuthServer, type ShadowOAuthTokens, type ShadowOAuthUser, type ShadowOAuthWorkspace, buildShadowOAuthDenyRedirect, parseShadowOAuthAuthorizeUrl, shadowOAuthAuthorizeApiPath };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,45 @@
1
+ interface ShadowOAuthAuthorizationRequest {
2
+ responseType: 'code';
3
+ clientId: string;
4
+ redirectUri: string;
5
+ scope: string;
6
+ state?: string;
7
+ sourceUrl: string;
8
+ }
9
+ interface ShadowOAuthAuthorizeUrlOptions {
10
+ allowedOrigins?: string[];
11
+ authorizePathnames?: string[];
12
+ }
13
+ declare const SHADOW_OAUTH_AUTHORIZE_PATHS: readonly ["/app/oauth/authorize", "/oauth/authorize"];
14
+ declare const SHADOW_OAUTH_SCOPE_GROUPS: readonly [{
15
+ readonly key: "user";
16
+ readonly scopes: readonly ["user:read", "user:email"];
17
+ }, {
18
+ readonly key: "servers";
19
+ readonly scopes: readonly ["servers:read", "servers:write"];
20
+ }, {
21
+ readonly key: "channels";
22
+ readonly scopes: readonly ["channels:read", "channels:write"];
23
+ }, {
24
+ readonly key: "messages";
25
+ readonly scopes: readonly ["messages:read", "messages:write"];
26
+ }, {
27
+ readonly key: "attachments";
28
+ readonly scopes: readonly ["attachments:read", "attachments:write"];
29
+ }, {
30
+ readonly key: "workspaces";
31
+ readonly scopes: readonly ["workspaces:read", "workspaces:write"];
32
+ }, {
33
+ readonly key: "buddies";
34
+ readonly scopes: readonly ["buddies:create", "buddies:manage"];
35
+ }, {
36
+ readonly key: "commerce";
37
+ readonly scopes: readonly ["commerce:read", "commerce:write"];
38
+ }];
39
+ declare function parseShadowOAuthAuthorizeUrl(input: string, options?: ShadowOAuthAuthorizeUrlOptions): ShadowOAuthAuthorizationRequest | null;
40
+ declare function shadowOAuthAuthorizeApiPath(request: ShadowOAuthAuthorizationRequest): string;
41
+ declare function buildShadowOAuthDenyRedirect(request: Pick<ShadowOAuthAuthorizationRequest, 'redirectUri' | 'state'>, error?: string): string;
42
+
1
43
  interface ShadowOAuthConfig {
2
44
  /** Your app's client_id from Shadow Developer Portal */
3
45
  clientId: string;
@@ -238,4 +280,4 @@ declare class ShadowOAuth {
238
280
  private oauthPost;
239
281
  }
240
282
 
241
- export { ShadowOAuth, type ShadowOAuthBuddy, type ShadowOAuthChannel, type ShadowOAuthCommerceEntitlementAccess, type ShadowOAuthCommerceEntitlementRedeemInput, type ShadowOAuthCommerceEntitlementRedeemResult, type ShadowOAuthCommerceEntitlementRedemption, type ShadowOAuthCommerceEntitlementSummary, type ShadowOAuthConfig, type ShadowOAuthMessage, type ShadowOAuthScope, type ShadowOAuthServer, type ShadowOAuthTokens, type ShadowOAuthUser, type ShadowOAuthWorkspace };
283
+ export { SHADOW_OAUTH_AUTHORIZE_PATHS, SHADOW_OAUTH_SCOPE_GROUPS, ShadowOAuth, type ShadowOAuthAuthorizationRequest, type ShadowOAuthAuthorizeUrlOptions, type ShadowOAuthBuddy, type ShadowOAuthChannel, type ShadowOAuthCommerceEntitlementAccess, type ShadowOAuthCommerceEntitlementRedeemInput, type ShadowOAuthCommerceEntitlementRedeemResult, type ShadowOAuthCommerceEntitlementRedemption, type ShadowOAuthCommerceEntitlementSummary, type ShadowOAuthConfig, type ShadowOAuthMessage, type ShadowOAuthScope, type ShadowOAuthServer, type ShadowOAuthTokens, type ShadowOAuthUser, type ShadowOAuthWorkspace, buildShadowOAuthDenyRedirect, parseShadowOAuthAuthorizeUrl, shadowOAuthAuthorizeApiPath };
package/dist/index.js CHANGED
@@ -1,3 +1,63 @@
1
+ // src/authorization.ts
2
+ var SHADOW_OAUTH_AUTHORIZE_PATHS = ["/app/oauth/authorize", "/oauth/authorize"];
3
+ var SHADOW_OAUTH_SCOPE_GROUPS = [
4
+ { key: "user", scopes: ["user:read", "user:email"] },
5
+ { key: "servers", scopes: ["servers:read", "servers:write"] },
6
+ { key: "channels", scopes: ["channels:read", "channels:write"] },
7
+ { key: "messages", scopes: ["messages:read", "messages:write"] },
8
+ { key: "attachments", scopes: ["attachments:read", "attachments:write"] },
9
+ { key: "workspaces", scopes: ["workspaces:read", "workspaces:write"] },
10
+ { key: "buddies", scopes: ["buddies:create", "buddies:manage"] },
11
+ { key: "commerce", scopes: ["commerce:read", "commerce:write"] }
12
+ ];
13
+ function originFor(value) {
14
+ try {
15
+ return new URL(value).origin;
16
+ } catch {
17
+ return null;
18
+ }
19
+ }
20
+ function parseShadowOAuthAuthorizeUrl(input, options = {}) {
21
+ let url;
22
+ try {
23
+ url = new URL(input);
24
+ } catch {
25
+ return null;
26
+ }
27
+ const allowedOrigins = options.allowedOrigins?.map(originFor).filter((origin) => Boolean(origin));
28
+ if (allowedOrigins?.length && !allowedOrigins.includes(url.origin)) return null;
29
+ const authorizePathnames = options.authorizePathnames ?? [...SHADOW_OAUTH_AUTHORIZE_PATHS];
30
+ if (!authorizePathnames.includes(url.pathname)) return null;
31
+ const responseType = url.searchParams.get("response_type") ?? "code";
32
+ const clientId = url.searchParams.get("client_id")?.trim();
33
+ const redirectUri = url.searchParams.get("redirect_uri")?.trim();
34
+ if (responseType !== "code" || !clientId || !redirectUri) return null;
35
+ return {
36
+ responseType: "code",
37
+ clientId,
38
+ redirectUri,
39
+ scope: url.searchParams.get("scope")?.trim() || "user:read",
40
+ state: url.searchParams.get("state") ?? void 0,
41
+ sourceUrl: url.toString()
42
+ };
43
+ }
44
+ function shadowOAuthAuthorizeApiPath(request) {
45
+ const params = new URLSearchParams({
46
+ response_type: request.responseType,
47
+ client_id: request.clientId,
48
+ redirect_uri: request.redirectUri,
49
+ scope: request.scope
50
+ });
51
+ if (request.state) params.set("state", request.state);
52
+ return `/api/oauth/authorize?${params.toString()}`;
53
+ }
54
+ function buildShadowOAuthDenyRedirect(request, error = "access_denied") {
55
+ const url = new URL(request.redirectUri);
56
+ url.searchParams.set("error", error);
57
+ if (request.state) url.searchParams.set("state", request.state);
58
+ return url.toString();
59
+ }
60
+
1
61
  // src/client.ts
2
62
  var DEFAULT_BASE_URL = "https://shadowob.com";
3
63
  var ShadowOAuth = class {
@@ -25,7 +85,7 @@ var ShadowOAuth = class {
25
85
  if (options?.state) {
26
86
  params.set("state", options.state);
27
87
  }
28
- return `${this.baseUrl}/oauth/authorize?${params.toString()}`;
88
+ return `${this.baseUrl}/app/oauth/authorize?${params.toString()}`;
29
89
  }
30
90
  /**
31
91
  * Exchange an authorization code for access and refresh tokens.
@@ -236,5 +296,10 @@ var ShadowOAuth = class {
236
296
  }
237
297
  };
238
298
  export {
239
- ShadowOAuth
299
+ SHADOW_OAUTH_AUTHORIZE_PATHS,
300
+ SHADOW_OAUTH_SCOPE_GROUPS,
301
+ ShadowOAuth,
302
+ buildShadowOAuthDenyRedirect,
303
+ parseShadowOAuthAuthorizeUrl,
304
+ shadowOAuthAuthorizeApiPath
240
305
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shadowob/oauth",
3
- "version": "1.1.6",
3
+ "version": "1.1.8",
4
4
  "description": "Shadow OAuth SDK — typed client for integrating Shadow OAuth login into third-party applications",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -12,6 +12,7 @@
12
12
  ".": {
13
13
  "types": "./dist/index.d.ts",
14
14
  "development": "./src/index.ts",
15
+ "react-native": "./src/index.ts",
15
16
  "import": "./dist/index.js",
16
17
  "require": "./dist/index.cjs",
17
18
  "default": "./dist/index.js"