@alien_org/sso-sdk-core 1.0.12 → 1.0.14
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 +1 -0
- package/dist/index.d.ts +115 -3
- package/dist/index.esm.js +225 -0
- package/dist/index.umd.js +1 -0
- package/package.json +18 -15
- package/dist/client.d.ts +0 -28
- package/dist/client.js +0 -185
- package/dist/errors.d.ts +0 -8
- package/dist/errors.js +0 -13
- package/dist/index.js +0 -3
- package/dist/schema.d.ts +0 -62
- package/dist/schema.js +0 -52
- package/dist/server.d.ts +0 -14
- package/dist/server.js +0 -59
- package/dist/utils.d.ts +0 -1
- package/dist/utils.js +0 -3
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var d=(a,o,s)=>new Promise((n,r)=>{var t=i=>{try{h(s.next(i))}catch(g){r(g)}},c=i=>{try{h(s.throw(i))}catch(g){r(g)}},h=i=>i.done?n(i.value):Promise.resolve(i.value).then(t,c);h((s=s.apply(a,o)).next())});Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("zod/v4-mini"),j=require("js-sha256"),S=e.z.object({code_challenge:e.z.string(),code_challenge_method:e.z.literal("S256")}),f=e.z.object({deep_link:e.z.string(),polling_code:e.z.string(),expired_at:e.z.number()}),_=e.z.object({polling_code:e.z.string()}),v=["pending","authorized","rejected","expired"],T=e.z.enum(v),m=e.z.object({status:T,authorization_code:e.z.optional(e.z.string())}),z=e.z.object({authorization_code:e.z.string(),code_verifier:e.z.string()}),y=e.z.object({access_token:e.z.string()}),R=e.z.object({access_token:e.z.string()}),k=e.z.object({is_valid:e.z.boolean(),access_token:e.z.optional(e.z.string())}),b=e.z.object({app_callback_session_address:e.z.string(),expired_at:e.z.number(),issued_at:e.z.number()});function w(a){return btoa(a).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function u(a){let o=a.replace(/-/g,"+").replace(/_/g,"/");for(;o.length%4;)o+="=";return atob(o)}const C="https://sso.alien.com",E=5e3,l="alien-sso_",p=(a,o)=>new URL(o,a).toString(),A=e.z.object({ssoBaseUrl:e.z.url(),providerAddress:e.z.string(),pollingInterval:e.z.optional(e.z.number())});class P{constructor(o){this.config=A.parse(o),this.ssoBaseUrl=this.config.ssoBaseUrl||C,this.providerAddress=this.config.providerAddress,this.pollingInterval=this.config.pollingInterval||E}generateCodeVerifier(o=128){let s;const n=typeof window!="undefined"&&window.crypto;if(n&&n.getRandomValues)s=new Uint8Array(o),n.getRandomValues(s);else{s=new Uint8Array(o);for(let t=0;t<o;t++)s[t]=Math.floor(Math.random()*256)}let r="";for(let t=0;t<s.length;t++)r+=String.fromCharCode(s[t]);return w(r)}generateCodeChallenge(o){return j.sha256(o)}generateDeeplink(){return d(this,null,function*(){const o=this.generateCodeVerifier(),s=this.generateCodeChallenge(o);sessionStorage.setItem(l+"code_verifier",o);const n=`${this.config.ssoBaseUrl}/sso/authorize`,r={code_challenge:s,code_challenge_method:"S256"};S.parse(r);const c=yield(yield fetch(n,{method:"POST",headers:{"Content-Type":"application/json","X-PROVIDER-ADDRESS":this.providerAddress},body:JSON.stringify(r)})).json();return f.parse(c)})}pollAuth(o){return d(this,null,function*(){const s={polling_code:o};_.parse(s);const n=yield fetch(p(this.config.ssoBaseUrl,"/sso/poll"),{method:"POST",headers:{"Content-Type":"application/json","X-PROVIDER-ADDRESS":this.providerAddress},body:JSON.stringify(s)});if(!n.ok)throw new Error(`Poll failed: ${n.statusText}`);const r=yield n.json();return m.parse(r)})}exchangeToken(o){return d(this,null,function*(){const s=sessionStorage.getItem(l+"code_verifier");if(!s)throw new Error("Missing code verifier.");const n={authorization_code:o,code_verifier:s};z.parse(n);const r=yield fetch(p(this.config.ssoBaseUrl,"/sso/access_token/exchange"),{method:"POST",headers:{"Content-Type":"application/json","X-PROVIDER-ADDRESS":this.providerAddress},body:JSON.stringify(n)});if(!r.ok)throw new Error(`ExchangeCode failed: ${r.statusText}`);const t=yield r.json(),c=y.parse(t);if(c.access_token)return localStorage.setItem(l+"access_token",c.access_token),c.access_token;throw new Error("Exchange failed")})}verifyAuth(){return d(this,null,function*(){const o=this.getAccessToken();if(!o)return!1;const s={access_token:o};R.parse(s);const n=yield fetch(p(this.config.ssoBaseUrl,"/sso/access_token/verify"),{method:"POST",headers:{"Content-Type":"application/json","X-PROVIDER-ADDRESS":this.providerAddress},body:JSON.stringify(s)});if(!n.ok)return!1;const r=yield n.json(),t=k.parse(r);return t.access_token&&localStorage.setItem(l+"access_token",t.access_token),t.is_valid})}getAccessToken(){return localStorage.getItem(l+"access_token")}getAuthData(){const o=this.getAccessToken();if(!o)return null;const s=o.split(".");if(s.length!==3)return null;let n;try{const t=u(s[0]);n=JSON.parse(t)}catch(t){return null}if(n.alg!=="HS256"||n.typ!=="JWT")return null;let r;try{const t=JSON.parse(u(s[1]));r=b.parse(t)}catch(t){return null}return r}logout(){localStorage.removeItem(l+"access_token"),sessionStorage.removeItem(l+"code_verifier")}}exports.AlienSsoClient=P;exports.AlienSsoClientSchema=A;exports.AuthorizeRequestSchema=S;exports.AuthorizeResponseSchema=f;exports.ExchangeCodeRequestSchema=z;exports.ExchangeCodeResponseSchema=y;exports.PollRequestSchema=_;exports.PollResponseSchema=m;exports.TokenInfoSchema=b;exports.VerifyTokenRequestSchema=R;exports.VerifyTokenResponseSchema=k;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,115 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export
|
|
1
|
+
import { z } from 'zod/v4-mini';
|
|
2
|
+
|
|
3
|
+
export declare class AlienSsoClient {
|
|
4
|
+
readonly config: AlienSsoClientConfig;
|
|
5
|
+
readonly pollingInterval: number;
|
|
6
|
+
readonly ssoBaseUrl: string;
|
|
7
|
+
readonly providerAddress: string;
|
|
8
|
+
constructor(config: AlienSsoClientConfig);
|
|
9
|
+
private generateCodeVerifier;
|
|
10
|
+
private generateCodeChallenge;
|
|
11
|
+
generateDeeplink(): Promise<AuthorizeResponse>;
|
|
12
|
+
pollAuth(pollingCode: string): Promise<PollResponse>;
|
|
13
|
+
exchangeToken(authorizationCode: string): Promise<string>;
|
|
14
|
+
verifyAuth(): Promise<boolean>;
|
|
15
|
+
getAccessToken(): string | null;
|
|
16
|
+
getAuthData(): TokenInfo | null;
|
|
17
|
+
logout(): void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export declare type AlienSsoClientConfig = z.infer<typeof AlienSsoClientSchema>;
|
|
21
|
+
|
|
22
|
+
export declare const AlienSsoClientSchema: z.ZodMiniObject<{
|
|
23
|
+
ssoBaseUrl: z.ZodMiniURL;
|
|
24
|
+
providerAddress: z.ZodMiniString<string>;
|
|
25
|
+
pollingInterval: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
26
|
+
}, z.core.$strip>;
|
|
27
|
+
|
|
28
|
+
export declare type AuthorizeRequest = z.infer<typeof AuthorizeRequestSchema>;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Authorize request/response schema
|
|
32
|
+
*/
|
|
33
|
+
export declare const AuthorizeRequestSchema: z.ZodMiniObject<{
|
|
34
|
+
code_challenge: z.ZodMiniString<string>;
|
|
35
|
+
code_challenge_method: z.ZodMiniLiteral<"S256">;
|
|
36
|
+
}, z.core.$strip>;
|
|
37
|
+
|
|
38
|
+
export declare type AuthorizeResponse = z.infer<typeof AuthorizeResponseSchema>;
|
|
39
|
+
|
|
40
|
+
export declare const AuthorizeResponseSchema: z.ZodMiniObject<{
|
|
41
|
+
deep_link: z.ZodMiniString<string>;
|
|
42
|
+
polling_code: z.ZodMiniString<string>;
|
|
43
|
+
expired_at: z.ZodMiniNumber<number>;
|
|
44
|
+
}, z.core.$strip>;
|
|
45
|
+
|
|
46
|
+
export declare type ExchangeCodeRequest = z.infer<typeof ExchangeCodeRequestSchema>;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* ExchangeCode request/response schema
|
|
50
|
+
*/
|
|
51
|
+
export declare const ExchangeCodeRequestSchema: z.ZodMiniObject<{
|
|
52
|
+
authorization_code: z.ZodMiniString<string>;
|
|
53
|
+
code_verifier: z.ZodMiniString<string>;
|
|
54
|
+
}, z.core.$strip>;
|
|
55
|
+
|
|
56
|
+
export declare type ExchangeCodeResponse = z.infer<typeof ExchangeCodeResponseSchema>;
|
|
57
|
+
|
|
58
|
+
export declare const ExchangeCodeResponseSchema: z.ZodMiniObject<{
|
|
59
|
+
access_token: z.ZodMiniString<string>;
|
|
60
|
+
}, z.core.$strip>;
|
|
61
|
+
|
|
62
|
+
export declare interface JWTHeader {
|
|
63
|
+
alg: string;
|
|
64
|
+
typ: string;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export declare type PollRequest = z.infer<typeof PollRequestSchema>;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Poll request/response schema
|
|
71
|
+
*/
|
|
72
|
+
export declare const PollRequestSchema: z.ZodMiniObject<{
|
|
73
|
+
polling_code: z.ZodMiniString<string>;
|
|
74
|
+
}, z.core.$strip>;
|
|
75
|
+
|
|
76
|
+
export declare type PollResponse = z.infer<typeof PollResponseSchema>;
|
|
77
|
+
|
|
78
|
+
export declare const PollResponseSchema: z.ZodMiniObject<{
|
|
79
|
+
status: z.ZodMiniEnum<{
|
|
80
|
+
pending: "pending";
|
|
81
|
+
authorized: "authorized";
|
|
82
|
+
rejected: "rejected";
|
|
83
|
+
expired: "expired";
|
|
84
|
+
}>;
|
|
85
|
+
authorization_code: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
86
|
+
}, z.core.$strip>;
|
|
87
|
+
|
|
88
|
+
export declare type TokenInfo = z.infer<typeof TokenInfoSchema>;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Token info schema
|
|
92
|
+
*/
|
|
93
|
+
export declare const TokenInfoSchema: z.ZodMiniObject<{
|
|
94
|
+
app_callback_session_address: z.ZodMiniString<string>;
|
|
95
|
+
expired_at: z.ZodMiniNumber<number>;
|
|
96
|
+
issued_at: z.ZodMiniNumber<number>;
|
|
97
|
+
}, z.core.$strip>;
|
|
98
|
+
|
|
99
|
+
export declare type VerifyTokenRequest = z.infer<typeof VerifyTokenRequestSchema>;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* VerifyToken request/response schema
|
|
103
|
+
*/
|
|
104
|
+
export declare const VerifyTokenRequestSchema: z.ZodMiniObject<{
|
|
105
|
+
access_token: z.ZodMiniString<string>;
|
|
106
|
+
}, z.core.$strip>;
|
|
107
|
+
|
|
108
|
+
export declare type VerifyTokenResponse = z.infer<typeof VerifyTokenResponseSchema>;
|
|
109
|
+
|
|
110
|
+
export declare const VerifyTokenResponseSchema: z.ZodMiniObject<{
|
|
111
|
+
is_valid: z.ZodMiniBoolean<boolean>;
|
|
112
|
+
access_token: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
113
|
+
}, z.core.$strip>;
|
|
114
|
+
|
|
115
|
+
export { }
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
var d = (a, o, s) => new Promise((n, r) => {
|
|
2
|
+
var t = (i) => {
|
|
3
|
+
try {
|
|
4
|
+
h(s.next(i));
|
|
5
|
+
} catch (p) {
|
|
6
|
+
r(p);
|
|
7
|
+
}
|
|
8
|
+
}, c = (i) => {
|
|
9
|
+
try {
|
|
10
|
+
h(s.throw(i));
|
|
11
|
+
} catch (p) {
|
|
12
|
+
r(p);
|
|
13
|
+
}
|
|
14
|
+
}, h = (i) => i.done ? n(i.value) : Promise.resolve(i.value).then(t, c);
|
|
15
|
+
h((s = s.apply(a, o)).next());
|
|
16
|
+
});
|
|
17
|
+
import { z as e } from "zod/v4-mini";
|
|
18
|
+
import { sha256 as f } from "js-sha256";
|
|
19
|
+
const _ = e.object({
|
|
20
|
+
code_challenge: e.string(),
|
|
21
|
+
code_challenge_method: e.literal("S256")
|
|
22
|
+
}), S = e.object({
|
|
23
|
+
deep_link: e.string(),
|
|
24
|
+
polling_code: e.string(),
|
|
25
|
+
expired_at: e.number()
|
|
26
|
+
}), m = e.object({
|
|
27
|
+
polling_code: e.string()
|
|
28
|
+
}), y = ["pending", "authorized", "rejected", "expired"], k = e.enum(y), b = e.object({
|
|
29
|
+
status: k,
|
|
30
|
+
authorization_code: e.optional(e.string())
|
|
31
|
+
}), R = e.object({
|
|
32
|
+
authorization_code: e.string(),
|
|
33
|
+
code_verifier: e.string()
|
|
34
|
+
}), A = e.object({
|
|
35
|
+
access_token: e.string()
|
|
36
|
+
}), j = e.object({
|
|
37
|
+
access_token: e.string()
|
|
38
|
+
}), v = e.object({
|
|
39
|
+
is_valid: e.boolean(),
|
|
40
|
+
access_token: e.optional(e.string())
|
|
41
|
+
}), w = e.object({
|
|
42
|
+
app_callback_session_address: e.string(),
|
|
43
|
+
expired_at: e.number(),
|
|
44
|
+
issued_at: e.number()
|
|
45
|
+
});
|
|
46
|
+
function E(a) {
|
|
47
|
+
return btoa(a).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
48
|
+
}
|
|
49
|
+
function u(a) {
|
|
50
|
+
let o = a.replace(/-/g, "+").replace(/_/g, "/");
|
|
51
|
+
for (; o.length % 4; )
|
|
52
|
+
o += "=";
|
|
53
|
+
return atob(o);
|
|
54
|
+
}
|
|
55
|
+
const T = "https://sso.alien.com", C = 5e3, l = "alien-sso_", g = (a, o) => new URL(o, a).toString(), O = e.object({
|
|
56
|
+
ssoBaseUrl: e.url(),
|
|
57
|
+
providerAddress: e.string(),
|
|
58
|
+
pollingInterval: e.optional(e.number())
|
|
59
|
+
});
|
|
60
|
+
class x {
|
|
61
|
+
constructor(o) {
|
|
62
|
+
this.config = O.parse(o), this.ssoBaseUrl = this.config.ssoBaseUrl || T, this.providerAddress = this.config.providerAddress, this.pollingInterval = this.config.pollingInterval || C;
|
|
63
|
+
}
|
|
64
|
+
generateCodeVerifier(o = 128) {
|
|
65
|
+
let s;
|
|
66
|
+
const n = typeof window != "undefined" && window.crypto;
|
|
67
|
+
if (n && n.getRandomValues)
|
|
68
|
+
s = new Uint8Array(o), n.getRandomValues(s);
|
|
69
|
+
else {
|
|
70
|
+
s = new Uint8Array(o);
|
|
71
|
+
for (let t = 0; t < o; t++)
|
|
72
|
+
s[t] = Math.floor(Math.random() * 256);
|
|
73
|
+
}
|
|
74
|
+
let r = "";
|
|
75
|
+
for (let t = 0; t < s.length; t++)
|
|
76
|
+
r += String.fromCharCode(s[t]);
|
|
77
|
+
return E(r);
|
|
78
|
+
}
|
|
79
|
+
generateCodeChallenge(o) {
|
|
80
|
+
return f(o);
|
|
81
|
+
}
|
|
82
|
+
generateDeeplink() {
|
|
83
|
+
return d(this, null, function* () {
|
|
84
|
+
const o = this.generateCodeVerifier(), s = this.generateCodeChallenge(o);
|
|
85
|
+
sessionStorage.setItem(l + "code_verifier", o);
|
|
86
|
+
const n = `${this.config.ssoBaseUrl}/sso/authorize`, r = {
|
|
87
|
+
code_challenge: s,
|
|
88
|
+
code_challenge_method: "S256"
|
|
89
|
+
};
|
|
90
|
+
_.parse(r);
|
|
91
|
+
const c = yield (yield fetch(n, {
|
|
92
|
+
method: "POST",
|
|
93
|
+
headers: {
|
|
94
|
+
"Content-Type": "application/json",
|
|
95
|
+
"X-PROVIDER-ADDRESS": this.providerAddress
|
|
96
|
+
},
|
|
97
|
+
body: JSON.stringify(r)
|
|
98
|
+
})).json();
|
|
99
|
+
return S.parse(c);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
pollAuth(o) {
|
|
103
|
+
return d(this, null, function* () {
|
|
104
|
+
const s = {
|
|
105
|
+
polling_code: o
|
|
106
|
+
};
|
|
107
|
+
m.parse(s);
|
|
108
|
+
const n = yield fetch(g(this.config.ssoBaseUrl, "/sso/poll"), {
|
|
109
|
+
method: "POST",
|
|
110
|
+
headers: {
|
|
111
|
+
"Content-Type": "application/json",
|
|
112
|
+
"X-PROVIDER-ADDRESS": this.providerAddress
|
|
113
|
+
},
|
|
114
|
+
body: JSON.stringify(s)
|
|
115
|
+
});
|
|
116
|
+
if (!n.ok)
|
|
117
|
+
throw new Error(`Poll failed: ${n.statusText}`);
|
|
118
|
+
const r = yield n.json();
|
|
119
|
+
return b.parse(r);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
exchangeToken(o) {
|
|
123
|
+
return d(this, null, function* () {
|
|
124
|
+
const s = sessionStorage.getItem(l + "code_verifier");
|
|
125
|
+
if (!s) throw new Error("Missing code verifier.");
|
|
126
|
+
const n = {
|
|
127
|
+
authorization_code: o,
|
|
128
|
+
code_verifier: s
|
|
129
|
+
};
|
|
130
|
+
R.parse(n);
|
|
131
|
+
const r = yield fetch(
|
|
132
|
+
g(this.config.ssoBaseUrl, "/sso/access_token/exchange"),
|
|
133
|
+
{
|
|
134
|
+
method: "POST",
|
|
135
|
+
headers: {
|
|
136
|
+
"Content-Type": "application/json",
|
|
137
|
+
"X-PROVIDER-ADDRESS": this.providerAddress
|
|
138
|
+
},
|
|
139
|
+
body: JSON.stringify(n)
|
|
140
|
+
}
|
|
141
|
+
);
|
|
142
|
+
if (!r.ok)
|
|
143
|
+
throw new Error(`ExchangeCode failed: ${r.statusText}`);
|
|
144
|
+
const t = yield r.json(), c = A.parse(t);
|
|
145
|
+
if (c.access_token)
|
|
146
|
+
return localStorage.setItem(
|
|
147
|
+
l + "access_token",
|
|
148
|
+
c.access_token
|
|
149
|
+
), c.access_token;
|
|
150
|
+
throw new Error("Exchange failed");
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
verifyAuth() {
|
|
154
|
+
return d(this, null, function* () {
|
|
155
|
+
const o = this.getAccessToken();
|
|
156
|
+
if (!o)
|
|
157
|
+
return !1;
|
|
158
|
+
const s = {
|
|
159
|
+
access_token: o
|
|
160
|
+
};
|
|
161
|
+
j.parse(s);
|
|
162
|
+
const n = yield fetch(
|
|
163
|
+
g(this.config.ssoBaseUrl, "/sso/access_token/verify"),
|
|
164
|
+
{
|
|
165
|
+
method: "POST",
|
|
166
|
+
headers: {
|
|
167
|
+
"Content-Type": "application/json",
|
|
168
|
+
"X-PROVIDER-ADDRESS": this.providerAddress
|
|
169
|
+
},
|
|
170
|
+
body: JSON.stringify(s)
|
|
171
|
+
}
|
|
172
|
+
);
|
|
173
|
+
if (!n.ok)
|
|
174
|
+
return !1;
|
|
175
|
+
const r = yield n.json(), t = v.parse(r);
|
|
176
|
+
return t.access_token && localStorage.setItem(
|
|
177
|
+
l + "access_token",
|
|
178
|
+
t.access_token
|
|
179
|
+
), t.is_valid;
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
getAccessToken() {
|
|
183
|
+
return localStorage.getItem(l + "access_token");
|
|
184
|
+
}
|
|
185
|
+
getAuthData() {
|
|
186
|
+
const o = this.getAccessToken();
|
|
187
|
+
if (!o) return null;
|
|
188
|
+
const s = o.split(".");
|
|
189
|
+
if (s.length !== 3)
|
|
190
|
+
return null;
|
|
191
|
+
let n;
|
|
192
|
+
try {
|
|
193
|
+
const t = u(s[0]);
|
|
194
|
+
n = JSON.parse(t);
|
|
195
|
+
} catch (t) {
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
if (n.alg !== "HS256" || n.typ !== "JWT")
|
|
199
|
+
return null;
|
|
200
|
+
let r;
|
|
201
|
+
try {
|
|
202
|
+
const t = JSON.parse(u(s[1]));
|
|
203
|
+
r = w.parse(t);
|
|
204
|
+
} catch (t) {
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
return r;
|
|
208
|
+
}
|
|
209
|
+
logout() {
|
|
210
|
+
localStorage.removeItem(l + "access_token"), sessionStorage.removeItem(l + "code_verifier");
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
export {
|
|
214
|
+
x as AlienSsoClient,
|
|
215
|
+
O as AlienSsoClientSchema,
|
|
216
|
+
_ as AuthorizeRequestSchema,
|
|
217
|
+
S as AuthorizeResponseSchema,
|
|
218
|
+
R as ExchangeCodeRequestSchema,
|
|
219
|
+
A as ExchangeCodeResponseSchema,
|
|
220
|
+
m as PollRequestSchema,
|
|
221
|
+
b as PollResponseSchema,
|
|
222
|
+
w as TokenInfoSchema,
|
|
223
|
+
j as VerifyTokenRequestSchema,
|
|
224
|
+
v as VerifyTokenResponseSchema
|
|
225
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(t,e){typeof exports=="object"&&typeof module!="undefined"?e(exports,require("zod/v4-mini"),require("js-sha256")):typeof define=="function"&&define.amd?define(["exports","zod/v4-mini","js-sha256"],e):(t=typeof globalThis!="undefined"?globalThis:t||self,e(t.AlienSsoCore={},t.Zod,t.jsSha256))})(this,(function(t,e,i){"use strict";var f=(t,e,i)=>new Promise((S,g)=>{var m=c=>{try{u(i.next(c))}catch(d){g(d)}},_=c=>{try{u(i.throw(c))}catch(d){g(d)}},u=c=>c.done?S(c.value):Promise.resolve(c.value).then(m,_);u((i=i.apply(t,e)).next())});const S=e.z.object({code_challenge:e.z.string(),code_challenge_method:e.z.literal("S256")}),g=e.z.object({deep_link:e.z.string(),polling_code:e.z.string(),expired_at:e.z.number()}),m=e.z.object({polling_code:e.z.string()}),_=["pending","authorized","rejected","expired"],u=e.z.enum(_),c=e.z.object({status:u,authorization_code:e.z.optional(e.z.string())}),d=e.z.object({authorization_code:e.z.string(),code_verifier:e.z.string()}),y=e.z.object({access_token:e.z.string()}),R=e.z.object({access_token:e.z.string()}),k=e.z.object({is_valid:e.z.boolean(),access_token:e.z.optional(e.z.string())}),A=e.z.object({app_callback_session_address:e.z.string(),expired_at:e.z.number(),issued_at:e.z.number()});function T(h){return btoa(h).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function j(h){let o=h.replace(/-/g,"+").replace(/_/g,"/");for(;o.length%4;)o+="=";return atob(o)}const C="https://sso.alien.com",w=5e3,l="alien-sso_",z=(h,o)=>new URL(o,h).toString(),b=e.z.object({ssoBaseUrl:e.z.url(),providerAddress:e.z.string(),pollingInterval:e.z.optional(e.z.number())});class E{constructor(o){this.config=b.parse(o),this.ssoBaseUrl=this.config.ssoBaseUrl||C,this.providerAddress=this.config.providerAddress,this.pollingInterval=this.config.pollingInterval||w}generateCodeVerifier(o=128){let s;const r=typeof window!="undefined"&&window.crypto;if(r&&r.getRandomValues)s=new Uint8Array(o),r.getRandomValues(s);else{s=new Uint8Array(o);for(let n=0;n<o;n++)s[n]=Math.floor(Math.random()*256)}let a="";for(let n=0;n<s.length;n++)a+=String.fromCharCode(s[n]);return T(a)}generateCodeChallenge(o){return i.sha256(o)}generateDeeplink(){return f(this,null,function*(){const o=this.generateCodeVerifier(),s=this.generateCodeChallenge(o);sessionStorage.setItem(l+"code_verifier",o);const r=`${this.config.ssoBaseUrl}/sso/authorize`,a={code_challenge:s,code_challenge_method:"S256"};S.parse(a);const p=yield(yield fetch(r,{method:"POST",headers:{"Content-Type":"application/json","X-PROVIDER-ADDRESS":this.providerAddress},body:JSON.stringify(a)})).json();return g.parse(p)})}pollAuth(o){return f(this,null,function*(){const s={polling_code:o};m.parse(s);const r=yield fetch(z(this.config.ssoBaseUrl,"/sso/poll"),{method:"POST",headers:{"Content-Type":"application/json","X-PROVIDER-ADDRESS":this.providerAddress},body:JSON.stringify(s)});if(!r.ok)throw new Error(`Poll failed: ${r.statusText}`);const a=yield r.json();return c.parse(a)})}exchangeToken(o){return f(this,null,function*(){const s=sessionStorage.getItem(l+"code_verifier");if(!s)throw new Error("Missing code verifier.");const r={authorization_code:o,code_verifier:s};d.parse(r);const a=yield fetch(z(this.config.ssoBaseUrl,"/sso/access_token/exchange"),{method:"POST",headers:{"Content-Type":"application/json","X-PROVIDER-ADDRESS":this.providerAddress},body:JSON.stringify(r)});if(!a.ok)throw new Error(`ExchangeCode failed: ${a.statusText}`);const n=yield a.json(),p=y.parse(n);if(p.access_token)return localStorage.setItem(l+"access_token",p.access_token),p.access_token;throw new Error("Exchange failed")})}verifyAuth(){return f(this,null,function*(){const o=this.getAccessToken();if(!o)return!1;const s={access_token:o};R.parse(s);const r=yield fetch(z(this.config.ssoBaseUrl,"/sso/access_token/verify"),{method:"POST",headers:{"Content-Type":"application/json","X-PROVIDER-ADDRESS":this.providerAddress},body:JSON.stringify(s)});if(!r.ok)return!1;const a=yield r.json(),n=k.parse(a);return n.access_token&&localStorage.setItem(l+"access_token",n.access_token),n.is_valid})}getAccessToken(){return localStorage.getItem(l+"access_token")}getAuthData(){const o=this.getAccessToken();if(!o)return null;const s=o.split(".");if(s.length!==3)return null;let r;try{const n=j(s[0]);r=JSON.parse(n)}catch(n){return null}if(r.alg!=="HS256"||r.typ!=="JWT")return null;let a;try{const n=JSON.parse(j(s[1]));a=A.parse(n)}catch(n){return null}return a}logout(){localStorage.removeItem(l+"access_token"),sessionStorage.removeItem(l+"code_verifier")}}t.AlienSsoClient=E,t.AlienSsoClientSchema=b,t.AuthorizeRequestSchema=S,t.AuthorizeResponseSchema=g,t.ExchangeCodeRequestSchema=d,t.ExchangeCodeResponseSchema=y,t.PollRequestSchema=m,t.PollResponseSchema=c,t.TokenInfoSchema=A,t.VerifyTokenRequestSchema=R,t.VerifyTokenResponseSchema=k,Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})}));
|
package/package.json
CHANGED
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alien_org/sso-sdk-core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.14",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/alien-id/sso-sdk-js.git"
|
|
7
7
|
},
|
|
8
|
+
"main": "./dist/index.cjs",
|
|
9
|
+
"module": "./dist/index.esm.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
8
11
|
"exports": {
|
|
9
|
-
".":
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
"typesVersions": {
|
|
14
|
-
"*": {
|
|
15
|
-
"*": ["dist/types/*.d.ts"]
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.esm.js",
|
|
15
|
+
"require": "./dist/index.cjs"
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
|
-
"files": [
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md"
|
|
21
|
+
],
|
|
19
22
|
"scripts": {
|
|
20
|
-
"build": "
|
|
23
|
+
"build": "vite build",
|
|
24
|
+
"dev": "vite build --watch",
|
|
21
25
|
"test": "jest",
|
|
22
26
|
"test:unit": "jest tests/unit",
|
|
23
27
|
"test:integration": "jest tests/integration",
|
|
@@ -26,7 +30,6 @@
|
|
|
26
30
|
"prepublishOnly": "npm run build"
|
|
27
31
|
},
|
|
28
32
|
"devDependencies": {
|
|
29
|
-
"@types/crypto-js": "^4.2.2",
|
|
30
33
|
"@types/express": "^5.0.3",
|
|
31
34
|
"@types/jest": "^30.0.0",
|
|
32
35
|
"@types/node": "^24.3.0",
|
|
@@ -42,12 +45,12 @@
|
|
|
42
45
|
"nock": "^14.0.10",
|
|
43
46
|
"prettier": "^3.6.2",
|
|
44
47
|
"ts-jest": "^29.4.1",
|
|
45
|
-
"turbo": "^2.5.6"
|
|
48
|
+
"turbo": "^2.5.6",
|
|
49
|
+
"vite": "^7.1.12",
|
|
50
|
+
"vite-plugin-dts": "^4.5.4"
|
|
46
51
|
},
|
|
47
52
|
"dependencies": {
|
|
48
|
-
"
|
|
49
|
-
"base64url": "^3.0.1",
|
|
50
|
-
"crypto-js": "^4.2.0",
|
|
53
|
+
"js-sha256": "^0.11.1",
|
|
51
54
|
"zod": "^4.1.5"
|
|
52
55
|
}
|
|
53
56
|
}
|
package/dist/client.d.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { AuthorizeResponse, TokenInfo } from './schema';
|
|
2
|
-
import { z } from 'zod/v4-mini';
|
|
3
|
-
export interface JWTHeader {
|
|
4
|
-
alg: string;
|
|
5
|
-
typ: string;
|
|
6
|
-
}
|
|
7
|
-
export declare const AlienSsoSdkClientSchema: z.ZodMiniObject<{
|
|
8
|
-
ssoBaseUrl: z.ZodMiniURL;
|
|
9
|
-
providerAddress: z.ZodMiniString<string>;
|
|
10
|
-
pollingInterval: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
11
|
-
}, z.core.$strip>;
|
|
12
|
-
export type AlienSsoSdkClientConfig = z.infer<typeof AlienSsoSdkClientSchema>;
|
|
13
|
-
export declare class AlienSsoSdkClient {
|
|
14
|
-
readonly config: AlienSsoSdkClientConfig;
|
|
15
|
-
readonly pollingInterval: number;
|
|
16
|
-
readonly ssoBaseUrl: string;
|
|
17
|
-
readonly providerAddress: string;
|
|
18
|
-
constructor(config: AlienSsoSdkClientConfig);
|
|
19
|
-
private generateCodeVerifier;
|
|
20
|
-
private generateCodeChallenge;
|
|
21
|
-
getAuthDeeplink(): Promise<AuthorizeResponse>;
|
|
22
|
-
pollAuth(pollingCode: string): Promise<string>;
|
|
23
|
-
exchangeToken(authorizationCode: string): Promise<string>;
|
|
24
|
-
verifyAuth(): Promise<boolean>;
|
|
25
|
-
getAccessToken(): string | null;
|
|
26
|
-
getAuthData(): TokenInfo | null;
|
|
27
|
-
logout(): void;
|
|
28
|
-
}
|
package/dist/client.js
DELETED
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
import { AuthorizeResponseSchema, ExchangeCodeRequestSchema, ExchangeCodeResponseSchema, AuthorizeRequestSchema, PollRequestSchema, PollResponseSchema, TokenInfoSchema, VerifyTokenRequestSchema, VerifyTokenResponseSchema, } from './schema';
|
|
2
|
-
import { z } from 'zod/v4-mini';
|
|
3
|
-
import base64url from 'base64url';
|
|
4
|
-
import CryptoJS from 'crypto-js';
|
|
5
|
-
import { joinUrl } from './utils';
|
|
6
|
-
const SSO_BASE_URL = 'https://sso.alien.com';
|
|
7
|
-
const POLLING_INTERVAL = 5000;
|
|
8
|
-
const STORAGE_KEY = 'alien-sso_';
|
|
9
|
-
export const AlienSsoSdkClientSchema = z.object({
|
|
10
|
-
ssoBaseUrl: z.url(),
|
|
11
|
-
providerAddress: z.string(),
|
|
12
|
-
pollingInterval: z.optional(z.number()),
|
|
13
|
-
});
|
|
14
|
-
export class AlienSsoSdkClient {
|
|
15
|
-
constructor(config) {
|
|
16
|
-
this.config = AlienSsoSdkClientSchema.parse(config);
|
|
17
|
-
this.ssoBaseUrl = this.config.ssoBaseUrl || SSO_BASE_URL;
|
|
18
|
-
this.providerAddress = this.config.providerAddress;
|
|
19
|
-
this.pollingInterval = this.config.pollingInterval || POLLING_INTERVAL;
|
|
20
|
-
}
|
|
21
|
-
generateCodeVerifier(length = 128) {
|
|
22
|
-
let array;
|
|
23
|
-
const cryptoObj = typeof window !== 'undefined' && window.crypto;
|
|
24
|
-
if (cryptoObj && cryptoObj.getRandomValues) {
|
|
25
|
-
array = new Uint8Array(length);
|
|
26
|
-
cryptoObj.getRandomValues(array);
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
array = new Uint8Array(length);
|
|
30
|
-
for (let i = 0; i < length; i++) {
|
|
31
|
-
array[i] = Math.floor(Math.random() * 256);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
let str = '';
|
|
35
|
-
for (let i = 0; i < array.length; i++) {
|
|
36
|
-
str += String.fromCharCode(array[i]);
|
|
37
|
-
}
|
|
38
|
-
return base64url.encode(str);
|
|
39
|
-
}
|
|
40
|
-
async generateCodeChallenge(codeVerifier) {
|
|
41
|
-
return CryptoJS.SHA256(codeVerifier).toString(CryptoJS.enc.Hex);
|
|
42
|
-
}
|
|
43
|
-
async getAuthDeeplink() {
|
|
44
|
-
const codeVerifier = this.generateCodeVerifier();
|
|
45
|
-
const codeChallenge = await this.generateCodeChallenge(codeVerifier);
|
|
46
|
-
sessionStorage.setItem(STORAGE_KEY + 'code_verifier', codeVerifier);
|
|
47
|
-
const authorizeUrl = `${this.config.ssoBaseUrl}/sso/authorize`;
|
|
48
|
-
const authorizePayload = {
|
|
49
|
-
code_challenge: codeChallenge,
|
|
50
|
-
code_challenge_method: 'S256'
|
|
51
|
-
};
|
|
52
|
-
AuthorizeRequestSchema.parse(authorizePayload);
|
|
53
|
-
const response = await fetch(authorizeUrl, {
|
|
54
|
-
method: 'POST',
|
|
55
|
-
headers: {
|
|
56
|
-
'Content-Type': 'application/json',
|
|
57
|
-
'X-PROVIDER-ADDRESS': this.providerAddress,
|
|
58
|
-
},
|
|
59
|
-
body: JSON.stringify(authorizePayload),
|
|
60
|
-
});
|
|
61
|
-
const json = await response.json();
|
|
62
|
-
return AuthorizeResponseSchema.parse(json);
|
|
63
|
-
}
|
|
64
|
-
async pollAuth(pollingCode) {
|
|
65
|
-
const pollPayload = {
|
|
66
|
-
polling_code: pollingCode,
|
|
67
|
-
};
|
|
68
|
-
PollRequestSchema.parse(pollPayload);
|
|
69
|
-
while (true) {
|
|
70
|
-
const response = await fetch(joinUrl(this.config.ssoBaseUrl, '/sso/poll'), {
|
|
71
|
-
method: 'POST',
|
|
72
|
-
headers: {
|
|
73
|
-
'Content-Type': 'application/json',
|
|
74
|
-
'X-PROVIDER-ADDRESS': this.providerAddress,
|
|
75
|
-
},
|
|
76
|
-
body: JSON.stringify(pollPayload),
|
|
77
|
-
});
|
|
78
|
-
if (!response.ok) {
|
|
79
|
-
throw new Error(`Poll failed: ${response.statusText}`);
|
|
80
|
-
}
|
|
81
|
-
const json = await response.json();
|
|
82
|
-
const pollResponse = PollResponseSchema.parse(json);
|
|
83
|
-
if (pollResponse.status === 'authorized' &&
|
|
84
|
-
pollResponse.authorization_code) {
|
|
85
|
-
return pollResponse.authorization_code;
|
|
86
|
-
}
|
|
87
|
-
if (pollResponse.status === 'pending') {
|
|
88
|
-
await new Promise((resolve) => setTimeout(resolve, this.pollingInterval));
|
|
89
|
-
}
|
|
90
|
-
else {
|
|
91
|
-
throw new Error(`Poll failed`);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
async exchangeToken(authorizationCode) {
|
|
96
|
-
const codeVerifier = sessionStorage.getItem(STORAGE_KEY + 'code_verifier');
|
|
97
|
-
if (!codeVerifier)
|
|
98
|
-
throw new Error('Missing code verifier.');
|
|
99
|
-
const exchangeCodePayload = {
|
|
100
|
-
authorization_code: authorizationCode,
|
|
101
|
-
code_verifier: codeVerifier,
|
|
102
|
-
};
|
|
103
|
-
ExchangeCodeRequestSchema.parse(exchangeCodePayload);
|
|
104
|
-
const response = await fetch(joinUrl(this.config.ssoBaseUrl, '/sso/access_token/exchange'), {
|
|
105
|
-
method: 'POST',
|
|
106
|
-
headers: {
|
|
107
|
-
'Content-Type': 'application/json',
|
|
108
|
-
'X-PROVIDER-ADDRESS': this.providerAddress,
|
|
109
|
-
},
|
|
110
|
-
body: JSON.stringify(exchangeCodePayload),
|
|
111
|
-
});
|
|
112
|
-
if (!response.ok) {
|
|
113
|
-
throw new Error(`ExchangeCode failed: ${response.statusText}`);
|
|
114
|
-
}
|
|
115
|
-
const json = await response.json();
|
|
116
|
-
const exchangeCodeResponse = ExchangeCodeResponseSchema.parse(json);
|
|
117
|
-
if (exchangeCodeResponse.access_token) {
|
|
118
|
-
localStorage.setItem(STORAGE_KEY + 'access_token', exchangeCodeResponse.access_token);
|
|
119
|
-
return exchangeCodeResponse.access_token;
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
throw new Error('Exchange failed');
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
async verifyAuth() {
|
|
126
|
-
const access_token = this.getAccessToken();
|
|
127
|
-
if (!access_token) {
|
|
128
|
-
throw new Error('Access token is invalid.');
|
|
129
|
-
}
|
|
130
|
-
const verifyTokenPayload = {
|
|
131
|
-
access_token,
|
|
132
|
-
};
|
|
133
|
-
VerifyTokenRequestSchema.parse(verifyTokenPayload);
|
|
134
|
-
const response = await fetch(joinUrl(this.config.ssoBaseUrl, '/sso/access_token/verify'), {
|
|
135
|
-
method: 'POST',
|
|
136
|
-
headers: {
|
|
137
|
-
'Content-Type': 'application/json',
|
|
138
|
-
'X-PROVIDER-ADDRESS': this.providerAddress,
|
|
139
|
-
},
|
|
140
|
-
body: JSON.stringify(verifyTokenPayload),
|
|
141
|
-
});
|
|
142
|
-
if (!response.ok) {
|
|
143
|
-
throw new Error(`VerifyToken failed: ${response.statusText}`);
|
|
144
|
-
}
|
|
145
|
-
const json = await response.json();
|
|
146
|
-
const verifyTokenResponse = VerifyTokenResponseSchema.parse(json);
|
|
147
|
-
return verifyTokenResponse.is_valid;
|
|
148
|
-
}
|
|
149
|
-
getAccessToken() {
|
|
150
|
-
return localStorage.getItem(STORAGE_KEY + 'access_token');
|
|
151
|
-
}
|
|
152
|
-
getAuthData() {
|
|
153
|
-
const token = this.getAccessToken();
|
|
154
|
-
if (!token)
|
|
155
|
-
return null;
|
|
156
|
-
const tokenParts = token.split('.');
|
|
157
|
-
if (tokenParts.length !== 3) {
|
|
158
|
-
return null;
|
|
159
|
-
}
|
|
160
|
-
let header;
|
|
161
|
-
try {
|
|
162
|
-
const headerJson = base64url.decode(tokenParts[0]);
|
|
163
|
-
header = JSON.parse(headerJson);
|
|
164
|
-
}
|
|
165
|
-
catch {
|
|
166
|
-
return null;
|
|
167
|
-
}
|
|
168
|
-
if (header.alg !== 'HS256' || header.typ !== 'JWT') {
|
|
169
|
-
return null;
|
|
170
|
-
}
|
|
171
|
-
let payload;
|
|
172
|
-
try {
|
|
173
|
-
const payloadJson = JSON.parse(base64url.decode(tokenParts[1]));
|
|
174
|
-
payload = TokenInfoSchema.parse(payloadJson);
|
|
175
|
-
}
|
|
176
|
-
catch {
|
|
177
|
-
return null;
|
|
178
|
-
}
|
|
179
|
-
return payload;
|
|
180
|
-
}
|
|
181
|
-
logout() {
|
|
182
|
-
localStorage.removeItem(STORAGE_KEY + 'access_token');
|
|
183
|
-
sessionStorage.removeItem(STORAGE_KEY + 'code_verifier');
|
|
184
|
-
}
|
|
185
|
-
}
|
package/dist/errors.d.ts
DELETED
package/dist/errors.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
class BaseError extends Error {
|
|
2
|
-
constructor(message) {
|
|
3
|
-
super(message);
|
|
4
|
-
this.name = this.constructor.name;
|
|
5
|
-
if (Error.captureStackTrace) {
|
|
6
|
-
Error.captureStackTrace(this, this.constructor);
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
export class ValidationError extends BaseError {
|
|
11
|
-
}
|
|
12
|
-
export class AuthenticationError extends BaseError {
|
|
13
|
-
}
|
package/dist/index.js
DELETED
package/dist/schema.d.ts
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod/v4-mini';
|
|
2
|
-
/**
|
|
3
|
-
* Authorize request/response schema
|
|
4
|
-
*/
|
|
5
|
-
export declare const AuthorizeRequestSchema: z.ZodMiniObject<{
|
|
6
|
-
code_challenge: z.ZodMiniString<string>;
|
|
7
|
-
code_challenge_method: z.ZodMiniLiteral<"S256">;
|
|
8
|
-
}, z.core.$strip>;
|
|
9
|
-
export type AuthorizeRequest = z.infer<typeof AuthorizeRequestSchema>;
|
|
10
|
-
export declare const AuthorizeResponseSchema: z.ZodMiniObject<{
|
|
11
|
-
deep_link: z.ZodMiniString<string>;
|
|
12
|
-
polling_code: z.ZodMiniString<string>;
|
|
13
|
-
expired_at: z.ZodMiniNumber<number>;
|
|
14
|
-
}, z.core.$strip>;
|
|
15
|
-
export type AuthorizeResponse = z.infer<typeof AuthorizeResponseSchema>;
|
|
16
|
-
/**
|
|
17
|
-
* Poll request/response schema
|
|
18
|
-
*/
|
|
19
|
-
export declare const PollRequestSchema: z.ZodMiniObject<{
|
|
20
|
-
polling_code: z.ZodMiniString<string>;
|
|
21
|
-
}, z.core.$strip>;
|
|
22
|
-
export type PollRequest = z.infer<typeof PollRequestSchema>;
|
|
23
|
-
export declare const PollResponseSchema: z.ZodMiniObject<{
|
|
24
|
-
status: z.ZodMiniEnum<{
|
|
25
|
-
pending: "pending";
|
|
26
|
-
authorized: "authorized";
|
|
27
|
-
}>;
|
|
28
|
-
authorization_code: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
29
|
-
}, z.core.$strip>;
|
|
30
|
-
export type PollResponse = z.infer<typeof PollResponseSchema>;
|
|
31
|
-
/**
|
|
32
|
-
* ExchangeCode request/response schema
|
|
33
|
-
*/
|
|
34
|
-
export declare const ExchangeCodeRequestSchema: z.ZodMiniObject<{
|
|
35
|
-
authorization_code: z.ZodMiniString<string>;
|
|
36
|
-
code_verifier: z.ZodMiniString<string>;
|
|
37
|
-
}, z.core.$strip>;
|
|
38
|
-
export type ExchangeCodeRequest = z.infer<typeof ExchangeCodeRequestSchema>;
|
|
39
|
-
export declare const ExchangeCodeResponseSchema: z.ZodMiniObject<{
|
|
40
|
-
access_token: z.ZodMiniString<string>;
|
|
41
|
-
}, z.core.$strip>;
|
|
42
|
-
export type ExchangeCodeResponse = z.infer<typeof ExchangeCodeResponseSchema>;
|
|
43
|
-
/**
|
|
44
|
-
* VerifyToken request/response schema
|
|
45
|
-
*/
|
|
46
|
-
export declare const VerifyTokenRequestSchema: z.ZodMiniObject<{
|
|
47
|
-
access_token: z.ZodMiniString<string>;
|
|
48
|
-
}, z.core.$strip>;
|
|
49
|
-
export type VerifyTokenRequest = z.infer<typeof VerifyTokenRequestSchema>;
|
|
50
|
-
export declare const VerifyTokenResponseSchema: z.ZodMiniObject<{
|
|
51
|
-
is_valid: z.ZodMiniBoolean<boolean>;
|
|
52
|
-
}, z.core.$strip>;
|
|
53
|
-
export type VerifyTokenResponse = z.infer<typeof VerifyTokenResponseSchema>;
|
|
54
|
-
/**
|
|
55
|
-
* Token info schema
|
|
56
|
-
*/
|
|
57
|
-
export declare const TokenInfoSchema: z.ZodMiniObject<{
|
|
58
|
-
app_callback_session_address: z.ZodMiniString<string>;
|
|
59
|
-
expired_at: z.ZodMiniNumber<number>;
|
|
60
|
-
issued_at: z.ZodMiniNumber<number>;
|
|
61
|
-
}, z.core.$strip>;
|
|
62
|
-
export type TokenInfo = z.infer<typeof TokenInfoSchema>;
|
package/dist/schema.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod/v4-mini';
|
|
2
|
-
/**
|
|
3
|
-
* Authorize request/response schema
|
|
4
|
-
*/
|
|
5
|
-
export const AuthorizeRequestSchema = z.object({
|
|
6
|
-
code_challenge: z.string(),
|
|
7
|
-
code_challenge_method: z.literal('S256'),
|
|
8
|
-
});
|
|
9
|
-
export const AuthorizeResponseSchema = z.object({
|
|
10
|
-
deep_link: z.string(),
|
|
11
|
-
polling_code: z.string(),
|
|
12
|
-
expired_at: z.number(),
|
|
13
|
-
});
|
|
14
|
-
/**
|
|
15
|
-
* Poll request/response schema
|
|
16
|
-
*/
|
|
17
|
-
export const PollRequestSchema = z.object({
|
|
18
|
-
polling_code: z.string(),
|
|
19
|
-
});
|
|
20
|
-
const status = ['pending', 'authorized'];
|
|
21
|
-
const StatusEnum = z.enum(status);
|
|
22
|
-
export const PollResponseSchema = z.object({
|
|
23
|
-
status: StatusEnum,
|
|
24
|
-
authorization_code: z.optional(z.string()),
|
|
25
|
-
});
|
|
26
|
-
/**
|
|
27
|
-
* ExchangeCode request/response schema
|
|
28
|
-
*/
|
|
29
|
-
export const ExchangeCodeRequestSchema = z.object({
|
|
30
|
-
authorization_code: z.string(),
|
|
31
|
-
code_verifier: z.string(),
|
|
32
|
-
});
|
|
33
|
-
export const ExchangeCodeResponseSchema = z.object({
|
|
34
|
-
access_token: z.string(),
|
|
35
|
-
});
|
|
36
|
-
/**
|
|
37
|
-
* VerifyToken request/response schema
|
|
38
|
-
*/
|
|
39
|
-
export const VerifyTokenRequestSchema = z.object({
|
|
40
|
-
access_token: z.string(),
|
|
41
|
-
});
|
|
42
|
-
export const VerifyTokenResponseSchema = z.object({
|
|
43
|
-
is_valid: z.boolean(),
|
|
44
|
-
});
|
|
45
|
-
/**
|
|
46
|
-
* Token info schema
|
|
47
|
-
*/
|
|
48
|
-
export const TokenInfoSchema = z.object({
|
|
49
|
-
app_callback_session_address: z.string(),
|
|
50
|
-
expired_at: z.number(),
|
|
51
|
-
issued_at: z.number(),
|
|
52
|
-
});
|
package/dist/server.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { AuthorizeResponse } from './schema';
|
|
2
|
-
import { z } from 'zod/v4-mini';
|
|
3
|
-
export declare const AlienSsoSdkServerConfigSchema: z.ZodMiniObject<{
|
|
4
|
-
providerAddress: z.ZodMiniString<string>;
|
|
5
|
-
providerPrivateKey: z.ZodMiniString<string>;
|
|
6
|
-
ssoBaseUrl: z.ZodMiniURL;
|
|
7
|
-
}, z.core.$strip>;
|
|
8
|
-
export type AlienSsoSdkServerConfig = z.infer<typeof AlienSsoSdkServerConfigSchema>;
|
|
9
|
-
export declare class AlienSsoSdkServer {
|
|
10
|
-
readonly config: AlienSsoSdkServerConfig;
|
|
11
|
-
readonly ssoBaseUrl: string;
|
|
12
|
-
constructor(config: AlienSsoSdkServerConfig);
|
|
13
|
-
authorize(codeChallenge: string): Promise<AuthorizeResponse | null>;
|
|
14
|
-
}
|
package/dist/server.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { AuthorizeResponseSchema, AuthorizeRequestSchema, } from './schema';
|
|
2
|
-
import { z } from 'zod/v4-mini';
|
|
3
|
-
import { signAsync } from '@noble/ed25519';
|
|
4
|
-
import { AuthenticationError, ValidationError } from './errors';
|
|
5
|
-
import { joinUrl } from './utils';
|
|
6
|
-
const DEFAULT_SSO_BASE_URL = 'https://sso.alien-api.com';
|
|
7
|
-
export const AlienSsoSdkServerConfigSchema = z.object({
|
|
8
|
-
providerAddress: z.string(),
|
|
9
|
-
providerPrivateKey: z.string(),
|
|
10
|
-
ssoBaseUrl: z.url(),
|
|
11
|
-
});
|
|
12
|
-
export class AlienSsoSdkServer {
|
|
13
|
-
constructor(config) {
|
|
14
|
-
const parsedConfig = AlienSsoSdkServerConfigSchema.parse(config);
|
|
15
|
-
this.config = parsedConfig;
|
|
16
|
-
this.ssoBaseUrl = parsedConfig.ssoBaseUrl || DEFAULT_SSO_BASE_URL;
|
|
17
|
-
}
|
|
18
|
-
async authorize(codeChallenge) {
|
|
19
|
-
if (!codeChallenge || codeChallenge.length !== 64) {
|
|
20
|
-
throw new ValidationError('Invalid code challenge');
|
|
21
|
-
}
|
|
22
|
-
// Note: order of fields important!
|
|
23
|
-
const signaturePayload = {
|
|
24
|
-
provider_address: this.config.providerAddress,
|
|
25
|
-
code_challenge: codeChallenge,
|
|
26
|
-
code_challenge_method: 'S256',
|
|
27
|
-
};
|
|
28
|
-
const message = JSON.stringify(signaturePayload);
|
|
29
|
-
const messageBytes = new TextEncoder().encode(message);
|
|
30
|
-
const privateKeyBytes = Buffer.from(this.config.providerPrivateKey, 'hex');
|
|
31
|
-
const signature = await signAsync(messageBytes, privateKeyBytes);
|
|
32
|
-
const authorizePayload = {
|
|
33
|
-
...signaturePayload,
|
|
34
|
-
provider_signature: Buffer.from(signature).toString('hex'),
|
|
35
|
-
};
|
|
36
|
-
AuthorizeRequestSchema.parse(authorizePayload);
|
|
37
|
-
const response = await fetch(joinUrl(this.config.ssoBaseUrl, '/authorize'), {
|
|
38
|
-
method: 'POST',
|
|
39
|
-
headers: {
|
|
40
|
-
'Content-Type': 'application/json',
|
|
41
|
-
},
|
|
42
|
-
body: JSON.stringify(authorizePayload),
|
|
43
|
-
});
|
|
44
|
-
if (!response.ok) {
|
|
45
|
-
throw new AuthenticationError(`SSO Router Authorization failed: ${response.status} ${response.statusText} ${await response.text()}`);
|
|
46
|
-
}
|
|
47
|
-
const json = await response.json();
|
|
48
|
-
const { deep_link, polling_code, expired_at } = AuthorizeResponseSchema.parse(json);
|
|
49
|
-
const deepLinkBytes = Buffer.from(deep_link, 'utf8');
|
|
50
|
-
const deepLinkSignature = await signAsync(deepLinkBytes, privateKeyBytes);
|
|
51
|
-
const deepLinkUrl = new URL(deep_link);
|
|
52
|
-
deepLinkUrl.searchParams.set('link_signature', Buffer.from(deepLinkSignature).toString('hex'));
|
|
53
|
-
return {
|
|
54
|
-
deep_link: deepLinkUrl.toString(),
|
|
55
|
-
polling_code,
|
|
56
|
-
expired_at,
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
}
|
package/dist/utils.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const joinUrl: (base: string, path: string) => string;
|
package/dist/utils.js
DELETED