@sentroy-co/client-sdk 2.13.7 → 2.13.9
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/auth/admin/index.d.ts +153 -0
- package/dist/auth/admin/index.d.ts.map +1 -0
- package/dist/auth/admin/index.js +228 -0
- package/dist/auth/admin/index.js.map +1 -0
- package/dist/auth/client.d.ts +212 -0
- package/dist/auth/client.d.ts.map +1 -0
- package/dist/auth/client.js +623 -0
- package/dist/auth/client.js.map +1 -0
- package/dist/auth/http.d.ts +19 -0
- package/dist/auth/http.d.ts.map +1 -0
- package/dist/auth/http.js +74 -0
- package/dist/auth/http.js.map +1 -0
- package/dist/auth/index.d.ts +16 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +20 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/react/index.d.ts +100 -0
- package/dist/auth/react/index.d.ts.map +1 -0
- package/dist/auth/react/index.js +231 -0
- package/dist/auth/react/index.js.map +1 -0
- package/dist/auth/types.d.ts +105 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +21 -0
- package/dist/auth/types.js.map +1 -0
- package/package.json +20 -1
- package/src/auth/admin/index.ts +387 -0
- package/src/auth/client.ts +778 -0
- package/src/auth/http.ts +101 -0
- package/src/auth/index.ts +35 -0
- package/src/auth/react/index.tsx +351 -0
- package/src/auth/types.ts +126 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import type { SentroyAuthUser, SignupResponse, LoginResponse, LoginOutcome, AuthTokensResponse } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Server-side Sentroy Auth admin SDK. **Node only — apiKey browser'a
|
|
4
|
+
* koymayın**; bu sınıf Project'in master `aps_` token'ını taşır.
|
|
5
|
+
*
|
|
6
|
+
* Tüm public auth endpoint'lerini apiKey'le proxy eder ve JWT'yi local
|
|
7
|
+
* verify edebilir (JWKS cache + RSA Subtle). RP backend tipik akış:
|
|
8
|
+
*
|
|
9
|
+
* const admin = new SentroyAuthAdmin({ projectSlug, apiKey })
|
|
10
|
+
* const out = await admin.users.signIn({ email, password })
|
|
11
|
+
* if (out.kind === "tokens") setCookie(out.data.accessToken, ...)
|
|
12
|
+
* else // MFA flow
|
|
13
|
+
*
|
|
14
|
+
* // Mid-request: verify
|
|
15
|
+
* const claims = await admin.verifyIdToken(req.cookies.accessToken)
|
|
16
|
+
*
|
|
17
|
+
* Token persistence yok — server-side request-scoped; caller cookie /
|
|
18
|
+
* session / DB nereye isterse oraya yazar.
|
|
19
|
+
*/
|
|
20
|
+
export interface SentroyAuthAdminOptions {
|
|
21
|
+
authBaseUrl?: string;
|
|
22
|
+
projectSlug: string;
|
|
23
|
+
apiKey: string;
|
|
24
|
+
/** JWKS cache TTL (saniye). Default 3600 (1 saat) — JWT rotation
|
|
25
|
+
* grace period'una uyumlu; daha agresif rotation yapan project'ler
|
|
26
|
+
* daha düşük set edebilir. */
|
|
27
|
+
jwksCacheTtl?: number;
|
|
28
|
+
}
|
|
29
|
+
export declare class SentroyAuthAdmin {
|
|
30
|
+
private readonly http;
|
|
31
|
+
private readonly jwksCacheTtl;
|
|
32
|
+
private cachedJwks;
|
|
33
|
+
constructor(opts: SentroyAuthAdminOptions);
|
|
34
|
+
get projectSlug(): string;
|
|
35
|
+
get baseUrl(): string;
|
|
36
|
+
users: {
|
|
37
|
+
/**
|
|
38
|
+
* Server-side signup proxy. apiKey backend'de — browser'a sızmaz.
|
|
39
|
+
* Email verification project config'ine bağlı: required ise
|
|
40
|
+
* `emailVerificationRequired: true` döner, tokens undefined.
|
|
41
|
+
*/
|
|
42
|
+
create: (input: {
|
|
43
|
+
email: string;
|
|
44
|
+
password: string;
|
|
45
|
+
displayName?: string;
|
|
46
|
+
metadata?: Record<string, unknown>;
|
|
47
|
+
}) => Promise<SignupResponse>;
|
|
48
|
+
/**
|
|
49
|
+
* Server-side login proxy. MFA-aware: tokens VEYA MFA challenge.
|
|
50
|
+
* RP backend `out.kind === "mfa"` ise kullanıcıdan code alıp
|
|
51
|
+
* `users.verifyMfa(...)` çağırır.
|
|
52
|
+
*/
|
|
53
|
+
signIn: (input: {
|
|
54
|
+
email: string;
|
|
55
|
+
password: string;
|
|
56
|
+
rememberMe?: boolean;
|
|
57
|
+
}) => Promise<LoginOutcome>;
|
|
58
|
+
/** MFA verify ikinci adımı — `signIn` kind:"mfa" döndüyse. */
|
|
59
|
+
verifyMfa: (input: {
|
|
60
|
+
mfaToken: string;
|
|
61
|
+
code?: string;
|
|
62
|
+
recoveryCode?: string;
|
|
63
|
+
}) => Promise<LoginResponse>;
|
|
64
|
+
/** Refresh access token (rotation). Yeni refresh + access döner. */
|
|
65
|
+
refresh: (refreshToken: string) => Promise<AuthTokensResponse>;
|
|
66
|
+
/** Logout (refresh token revoke). */
|
|
67
|
+
signOut: (refreshToken: string) => Promise<void>;
|
|
68
|
+
/** Verify email — link'ten gelen token. */
|
|
69
|
+
verifyEmail: (token: string) => Promise<{
|
|
70
|
+
user: SentroyAuthUser;
|
|
71
|
+
}>;
|
|
72
|
+
/** Password reset mail tetikle. */
|
|
73
|
+
requestPasswordReset: (email: string) => Promise<void>;
|
|
74
|
+
/** Reset token + yeni şifre ile finalize. */
|
|
75
|
+
confirmPasswordReset: (input: {
|
|
76
|
+
token: string;
|
|
77
|
+
newPassword: string;
|
|
78
|
+
}) => Promise<{
|
|
79
|
+
user: SentroyAuthUser;
|
|
80
|
+
}>;
|
|
81
|
+
/** Magic-link mail tetikle. */
|
|
82
|
+
sendMagicLink: (input: {
|
|
83
|
+
email: string;
|
|
84
|
+
redirectUri?: string;
|
|
85
|
+
}) => Promise<void>;
|
|
86
|
+
/** Magic-link token consume → login. */
|
|
87
|
+
consumeMagicLink: (token: string) => Promise<LoginResponse>;
|
|
88
|
+
/** Davet token'ı ile yeni hesap + login. */
|
|
89
|
+
acceptInvitation: (input: {
|
|
90
|
+
token: string;
|
|
91
|
+
password: string;
|
|
92
|
+
displayName?: string;
|
|
93
|
+
}) => Promise<LoginResponse>;
|
|
94
|
+
/**
|
|
95
|
+
* Access token ile remote /me — JWT'ye bağımlı kalmadan canlı
|
|
96
|
+
* profile çek. Token expire ise SentroyAuthError fırlatır.
|
|
97
|
+
*/
|
|
98
|
+
getUser: (accessToken: string) => Promise<SentroyAuthUser>;
|
|
99
|
+
/**
|
|
100
|
+
* Token bazlı userinfo (OIDC tarzı). `/userinfo` claims response —
|
|
101
|
+
* SentroyAuthUser shape'inden daha minimal olabilir.
|
|
102
|
+
*/
|
|
103
|
+
getUserinfo: (accessToken: string) => Promise<{
|
|
104
|
+
sub: string;
|
|
105
|
+
email?: string;
|
|
106
|
+
email_verified?: boolean;
|
|
107
|
+
name?: string;
|
|
108
|
+
picture?: string;
|
|
109
|
+
}>;
|
|
110
|
+
/**
|
|
111
|
+
* Admin list (paginated). **Şu an public API yok** — dashboard
|
|
112
|
+
* cookie-auth `/api/companies/[slug]/auth-projects/[id]/users`
|
|
113
|
+
* kullan. v2'de stk_ token'lı admin endpoint açılacak.
|
|
114
|
+
*/
|
|
115
|
+
list: (_opts?: {
|
|
116
|
+
limit?: number;
|
|
117
|
+
skip?: number;
|
|
118
|
+
emailVerified?: boolean;
|
|
119
|
+
}) => Promise<{
|
|
120
|
+
items: SentroyAuthUser[];
|
|
121
|
+
pagination: {
|
|
122
|
+
total: number;
|
|
123
|
+
limit: number;
|
|
124
|
+
skip: number;
|
|
125
|
+
};
|
|
126
|
+
}>;
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* Local verify — JWKS cache'lenir (default 1h TTL, opts ile değişir),
|
|
130
|
+
* JWT signature RS256 ile WebCrypto Subtle üzerinden verify edilir.
|
|
131
|
+
* `iss`/`aud` claim eşleşmesi de kontrol edilir.
|
|
132
|
+
*
|
|
133
|
+
* Throw'lar: malformed JWT, expired, iss/aud mismatch, key not found,
|
|
134
|
+
* signature mismatch. Tipik kullanım `try/catch` içinde — fail ise
|
|
135
|
+
* 401 dön.
|
|
136
|
+
*/
|
|
137
|
+
verifyIdToken(token: string): Promise<{
|
|
138
|
+
sub: string;
|
|
139
|
+
email?: string;
|
|
140
|
+
email_verified?: boolean;
|
|
141
|
+
name?: string;
|
|
142
|
+
picture?: string;
|
|
143
|
+
iss: string;
|
|
144
|
+
aud: string;
|
|
145
|
+
iat: number;
|
|
146
|
+
exp: number;
|
|
147
|
+
[claim: string]: unknown;
|
|
148
|
+
}>;
|
|
149
|
+
/** JWKS cache'ini elle temizle (key rotation sonrası). */
|
|
150
|
+
invalidateJwksCache(): void;
|
|
151
|
+
private fetchJwks;
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/admin/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,aAAa,EACb,YAAY,EACZ,kBAAkB,EAEnB,MAAM,UAAU,CAAA;AAEjB;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,uBAAuB;IACtC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd;;mCAE+B;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAOD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAU;IAC/B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;IACrC,OAAO,CAAC,UAAU,CAA0B;gBAEhC,IAAI,EAAE,uBAAuB;IAKzC,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,OAAO,IAAI,MAAM,CAEpB;IAID,KAAK;QACH;;;;WAIG;wBACa;YACd,KAAK,EAAE,MAAM,CAAA;YACb,QAAQ,EAAE,MAAM,CAAA;YAChB,WAAW,CAAC,EAAE,MAAM,CAAA;YACpB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;SACnC,KAAG,OAAO,CAAC,cAAc,CAAC;QAM3B;;;;WAIG;wBACmB;YACpB,KAAK,EAAE,MAAM,CAAA;YACb,QAAQ,EAAE,MAAM,CAAA;YAChB,UAAU,CAAC,EAAE,OAAO,CAAA;SACrB,KAAG,OAAO,CAAC,YAAY,CAAC;QAUzB,8DAA8D;2BAC3C;YACjB,QAAQ,EAAE,MAAM,CAAA;YAChB,IAAI,CAAC,EAAE,MAAM,CAAA;YACb,YAAY,CAAC,EAAE,MAAM,CAAA;SACtB,KAAG,OAAO,CAAC,aAAa,CAAC;QAM1B,oEAAoE;gCAC5C,MAAM,KAAG,OAAO,CAAC,kBAAkB,CAAC;QAM5D,qCAAqC;gCACb,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;QAQ9C,2CAA2C;6BACtB,MAAM,KAAG,OAAO,CAAC;YAAE,IAAI,EAAE,eAAe,CAAA;SAAE,CAAC;QAMhE,mCAAmC;sCACL,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;QAQpD,6CAA6C;sCACf;YAC5B,KAAK,EAAE,MAAM,CAAA;YACb,WAAW,EAAE,MAAM,CAAA;SACpB,KAAG,OAAO,CAAC;YAAE,IAAI,EAAE,eAAe,CAAA;SAAE,CAAC;QAMtC,+BAA+B;+BACR;YACrB,KAAK,EAAE,MAAM,CAAA;YACb,WAAW,CAAC,EAAE,MAAM,CAAA;SACrB,KAAG,OAAO,CAAC,IAAI,CAAC;QAQjB,wCAAwC;kCACd,MAAM,KAAG,OAAO,CAAC,aAAa,CAAC;QAMzD,4CAA4C;kCAClB;YACxB,KAAK,EAAE,MAAM,CAAA;YACb,QAAQ,EAAE,MAAM,CAAA;YAChB,WAAW,CAAC,EAAE,MAAM,CAAA;SACrB,KAAG,OAAO,CAAC,aAAa,CAAC;QAM1B;;;WAGG;+BACoB,MAAM,KAAG,OAAO,CAAC,eAAe,CAAC;QAMxD;;;WAGG;mCAEY,MAAM,KAClB,OAAO,CAAC;YACT,GAAG,EAAE,MAAM,CAAA;YACX,KAAK,CAAC,EAAE,MAAM,CAAA;YACd,cAAc,CAAC,EAAE,OAAO,CAAA;YACxB,IAAI,CAAC,EAAE,MAAM,CAAA;YACb,OAAO,CAAC,EAAE,MAAM,CAAA;SACjB,CAAC;QAMF;;;;WAIG;uBACW;YACZ,KAAK,CAAC,EAAE,MAAM,CAAA;YACd,IAAI,CAAC,EAAE,MAAM,CAAA;YACb,aAAa,CAAC,EAAE,OAAO,CAAA;SACxB,KAAQ,OAAO,CAAC;YACf,KAAK,EAAE,eAAe,EAAE,CAAA;YACxB,UAAU,EAAE;gBAAE,KAAK,EAAE,MAAM,CAAC;gBAAC,KAAK,EAAE,MAAM,CAAC;gBAAC,IAAI,EAAE,MAAM,CAAA;aAAE,CAAA;SAC3D,CAAC;MAKH;IAID;;;;;;;;OAQG;IACG,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAC1C,GAAG,EAAE,MAAM,CAAA;QACX,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,cAAc,CAAC,EAAE,OAAO,CAAA;QACxB,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,GAAG,EAAE,MAAM,CAAA;QACX,GAAG,EAAE,MAAM,CAAA;QACX,GAAG,EAAE,MAAM,CAAA;QACX,GAAG,EAAE,MAAM,CAAA;QACX,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;KACzB,CAAC;IAmDF,0DAA0D;IAC1D,mBAAmB,IAAI,IAAI;YAIb,SAAS;CAaxB"}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SentroyAuthAdmin = void 0;
|
|
4
|
+
const http_1 = require("../http");
|
|
5
|
+
class SentroyAuthAdmin {
|
|
6
|
+
http;
|
|
7
|
+
jwksCacheTtl;
|
|
8
|
+
cachedJwks = null;
|
|
9
|
+
constructor(opts) {
|
|
10
|
+
this.http = new http_1.AuthHttp(opts);
|
|
11
|
+
this.jwksCacheTtl = opts.jwksCacheTtl ?? 3600;
|
|
12
|
+
}
|
|
13
|
+
get projectSlug() {
|
|
14
|
+
return this.http.projectSlug;
|
|
15
|
+
}
|
|
16
|
+
get baseUrl() {
|
|
17
|
+
return this.http.baseUrl;
|
|
18
|
+
}
|
|
19
|
+
// ─── User pool admin ──────────────────────────────────────────────────
|
|
20
|
+
users = {
|
|
21
|
+
/**
|
|
22
|
+
* Server-side signup proxy. apiKey backend'de — browser'a sızmaz.
|
|
23
|
+
* Email verification project config'ine bağlı: required ise
|
|
24
|
+
* `emailVerificationRequired: true` döner, tokens undefined.
|
|
25
|
+
*/
|
|
26
|
+
create: (input) => this.http.request("/signup", {
|
|
27
|
+
method: "POST",
|
|
28
|
+
json: input,
|
|
29
|
+
}),
|
|
30
|
+
/**
|
|
31
|
+
* Server-side login proxy. MFA-aware: tokens VEYA MFA challenge.
|
|
32
|
+
* RP backend `out.kind === "mfa"` ise kullanıcıdan code alıp
|
|
33
|
+
* `users.verifyMfa(...)` çağırır.
|
|
34
|
+
*/
|
|
35
|
+
signIn: async (input) => {
|
|
36
|
+
const res = await this.http.request("/login", { method: "POST", json: input });
|
|
37
|
+
if ("mfaRequired" in res && res.mfaRequired) {
|
|
38
|
+
return { kind: "mfa", data: res };
|
|
39
|
+
}
|
|
40
|
+
return { kind: "tokens", data: res };
|
|
41
|
+
},
|
|
42
|
+
/** MFA verify ikinci adımı — `signIn` kind:"mfa" döndüyse. */
|
|
43
|
+
verifyMfa: (input) => this.http.request("/login/mfa/verify", {
|
|
44
|
+
method: "POST",
|
|
45
|
+
json: input,
|
|
46
|
+
}),
|
|
47
|
+
/** Refresh access token (rotation). Yeni refresh + access döner. */
|
|
48
|
+
refresh: (refreshToken) => this.http.request("/refresh", {
|
|
49
|
+
method: "POST",
|
|
50
|
+
json: { refreshToken },
|
|
51
|
+
}),
|
|
52
|
+
/** Logout (refresh token revoke). */
|
|
53
|
+
signOut: (refreshToken) => this.http
|
|
54
|
+
.request("/logout", {
|
|
55
|
+
method: "POST",
|
|
56
|
+
json: { refreshToken },
|
|
57
|
+
})
|
|
58
|
+
.then(() => undefined),
|
|
59
|
+
/** Verify email — link'ten gelen token. */
|
|
60
|
+
verifyEmail: (token) => this.http.request("/verify-email", {
|
|
61
|
+
method: "POST",
|
|
62
|
+
json: { token },
|
|
63
|
+
}),
|
|
64
|
+
/** Password reset mail tetikle. */
|
|
65
|
+
requestPasswordReset: (email) => this.http
|
|
66
|
+
.request("/password-reset/request", {
|
|
67
|
+
method: "POST",
|
|
68
|
+
json: { email },
|
|
69
|
+
})
|
|
70
|
+
.then(() => undefined),
|
|
71
|
+
/** Reset token + yeni şifre ile finalize. */
|
|
72
|
+
confirmPasswordReset: (input) => this.http.request("/password-reset/confirm", {
|
|
73
|
+
method: "POST",
|
|
74
|
+
json: input,
|
|
75
|
+
}),
|
|
76
|
+
/** Magic-link mail tetikle. */
|
|
77
|
+
sendMagicLink: (input) => this.http
|
|
78
|
+
.request("/magic-link/request", {
|
|
79
|
+
method: "POST",
|
|
80
|
+
json: input,
|
|
81
|
+
})
|
|
82
|
+
.then(() => undefined),
|
|
83
|
+
/** Magic-link token consume → login. */
|
|
84
|
+
consumeMagicLink: (token) => this.http.request("/magic-link/consume", {
|
|
85
|
+
method: "POST",
|
|
86
|
+
json: { token },
|
|
87
|
+
}),
|
|
88
|
+
/** Davet token'ı ile yeni hesap + login. */
|
|
89
|
+
acceptInvitation: (input) => this.http.request("/invitation/accept", {
|
|
90
|
+
method: "POST",
|
|
91
|
+
json: input,
|
|
92
|
+
}),
|
|
93
|
+
/**
|
|
94
|
+
* Access token ile remote /me — JWT'ye bağımlı kalmadan canlı
|
|
95
|
+
* profile çek. Token expire ise SentroyAuthError fırlatır.
|
|
96
|
+
*/
|
|
97
|
+
getUser: (accessToken) => this.http.request("/me", {
|
|
98
|
+
method: "GET",
|
|
99
|
+
bearer: accessToken,
|
|
100
|
+
}),
|
|
101
|
+
/**
|
|
102
|
+
* Token bazlı userinfo (OIDC tarzı). `/userinfo` claims response —
|
|
103
|
+
* SentroyAuthUser shape'inden daha minimal olabilir.
|
|
104
|
+
*/
|
|
105
|
+
getUserinfo: (accessToken) => this.http.request("/userinfo", {
|
|
106
|
+
method: "GET",
|
|
107
|
+
bearer: accessToken,
|
|
108
|
+
}),
|
|
109
|
+
/**
|
|
110
|
+
* Admin list (paginated). **Şu an public API yok** — dashboard
|
|
111
|
+
* cookie-auth `/api/companies/[slug]/auth-projects/[id]/users`
|
|
112
|
+
* kullan. v2'de stk_ token'lı admin endpoint açılacak.
|
|
113
|
+
*/
|
|
114
|
+
list: (_opts = {}) => {
|
|
115
|
+
throw new Error("admin.users.list requires session-authenticated admin API; use dashboard /api/companies/[slug]/auth-projects/[id]/users instead. (v2 admin SDK will proxy this with stk_ tokens.)");
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
// ─── ID token verification ─────────────────────────────────────────────
|
|
119
|
+
/**
|
|
120
|
+
* Local verify — JWKS cache'lenir (default 1h TTL, opts ile değişir),
|
|
121
|
+
* JWT signature RS256 ile WebCrypto Subtle üzerinden verify edilir.
|
|
122
|
+
* `iss`/`aud` claim eşleşmesi de kontrol edilir.
|
|
123
|
+
*
|
|
124
|
+
* Throw'lar: malformed JWT, expired, iss/aud mismatch, key not found,
|
|
125
|
+
* signature mismatch. Tipik kullanım `try/catch` içinde — fail ise
|
|
126
|
+
* 401 dön.
|
|
127
|
+
*/
|
|
128
|
+
async verifyIdToken(token) {
|
|
129
|
+
const parts = token.split(".");
|
|
130
|
+
if (parts.length !== 3) {
|
|
131
|
+
throw new Error("Malformed JWT — expected three segments.");
|
|
132
|
+
}
|
|
133
|
+
const [headerB64, payloadB64, sigB64] = parts;
|
|
134
|
+
const header = JSON.parse(decodeBase64Url(headerB64));
|
|
135
|
+
if (header.alg !== "RS256") {
|
|
136
|
+
throw new Error("Only RS256 supported.");
|
|
137
|
+
}
|
|
138
|
+
const claims = JSON.parse(decodeBase64Url(payloadB64));
|
|
139
|
+
if (typeof claims.exp !== "number" || claims.exp * 1000 < Date.now()) {
|
|
140
|
+
throw new Error("Token expired.");
|
|
141
|
+
}
|
|
142
|
+
const expectedIssSuffix = `/p/${this.http.projectSlug}`;
|
|
143
|
+
if (typeof claims.iss !== "string" ||
|
|
144
|
+
!claims.iss.endsWith(expectedIssSuffix)) {
|
|
145
|
+
throw new Error("Issuer mismatch.");
|
|
146
|
+
}
|
|
147
|
+
// aud == project apiKeyPrefix (first 12 chars of api key)
|
|
148
|
+
if (typeof claims.aud !== "string" ||
|
|
149
|
+
!this.http.apiKey?.startsWith(claims.aud)) {
|
|
150
|
+
throw new Error("Audience mismatch.");
|
|
151
|
+
}
|
|
152
|
+
const jwks = await this.fetchJwks();
|
|
153
|
+
const key = jwks.keys.find((k) => k.kid === header.kid) ?? jwks.keys[0];
|
|
154
|
+
if (!key)
|
|
155
|
+
throw new Error("No public key in JWKS.");
|
|
156
|
+
await verifyRsaSignature({
|
|
157
|
+
data: `${headerB64}.${payloadB64}`,
|
|
158
|
+
sigB64,
|
|
159
|
+
jwk: key,
|
|
160
|
+
});
|
|
161
|
+
return claims;
|
|
162
|
+
}
|
|
163
|
+
/** JWKS cache'ini elle temizle (key rotation sonrası). */
|
|
164
|
+
invalidateJwksCache() {
|
|
165
|
+
this.cachedJwks = null;
|
|
166
|
+
}
|
|
167
|
+
async fetchJwks() {
|
|
168
|
+
if (this.cachedJwks && this.cachedJwks.expiresAt > Date.now()) {
|
|
169
|
+
return { keys: this.cachedJwks.keys };
|
|
170
|
+
}
|
|
171
|
+
const jwks = await this.http.request("/jwks.json", { method: "GET" });
|
|
172
|
+
this.cachedJwks = {
|
|
173
|
+
keys: jwks.keys,
|
|
174
|
+
expiresAt: Date.now() + this.jwksCacheTtl * 1000,
|
|
175
|
+
};
|
|
176
|
+
return jwks;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
exports.SentroyAuthAdmin = SentroyAuthAdmin;
|
|
180
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────
|
|
181
|
+
function decodeBase64Url(s) {
|
|
182
|
+
const padded = s.replace(/-/g, "+").replace(/_/g, "/");
|
|
183
|
+
const pad = padded.length % 4 === 0 ? "" : "=".repeat(4 - (padded.length % 4));
|
|
184
|
+
if (typeof atob === "function") {
|
|
185
|
+
const binary = atob(padded + pad);
|
|
186
|
+
const bytes = new Uint8Array(binary.length);
|
|
187
|
+
for (let i = 0; i < binary.length; i++)
|
|
188
|
+
bytes[i] = binary.charCodeAt(i);
|
|
189
|
+
return new TextDecoder().decode(bytes);
|
|
190
|
+
}
|
|
191
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
192
|
+
const B = globalThis.Buffer;
|
|
193
|
+
if (B)
|
|
194
|
+
return B.from(padded + pad, "base64").toString("utf8");
|
|
195
|
+
throw new Error("No base64 decoder available");
|
|
196
|
+
}
|
|
197
|
+
function base64UrlToBytes(s) {
|
|
198
|
+
const padded = s.replace(/-/g, "+").replace(/_/g, "/");
|
|
199
|
+
const pad = padded.length % 4 === 0 ? "" : "=".repeat(4 - (padded.length % 4));
|
|
200
|
+
if (typeof atob === "function") {
|
|
201
|
+
const binary = atob(padded + pad);
|
|
202
|
+
const bytes = new Uint8Array(binary.length);
|
|
203
|
+
for (let i = 0; i < binary.length; i++)
|
|
204
|
+
bytes[i] = binary.charCodeAt(i);
|
|
205
|
+
return bytes;
|
|
206
|
+
}
|
|
207
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
208
|
+
const B = globalThis.Buffer;
|
|
209
|
+
if (B)
|
|
210
|
+
return new Uint8Array(B.from(padded + pad, "base64"));
|
|
211
|
+
throw new Error("No base64 decoder available");
|
|
212
|
+
}
|
|
213
|
+
async function verifyRsaSignature(input) {
|
|
214
|
+
// Browser + modern Node (>=18) have crypto.subtle. Tek kod yolu.
|
|
215
|
+
const subtle = typeof crypto !== "undefined" && crypto.subtle ? crypto.subtle : null;
|
|
216
|
+
if (!subtle) {
|
|
217
|
+
throw new Error("Web Crypto unavailable — upgrade Node >= 18 or run in a browser.");
|
|
218
|
+
}
|
|
219
|
+
const key = await subtle.importKey("jwk", input.jwk, { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" }, false, ["verify"]);
|
|
220
|
+
// Web Crypto types want ArrayBuffer-backed BufferSource. Bytes are
|
|
221
|
+
// created fresh from base64 decode so they are ArrayBuffer-safe.
|
|
222
|
+
const sigBytes = base64UrlToBytes(input.sigB64);
|
|
223
|
+
const dataBytes = new TextEncoder().encode(input.data);
|
|
224
|
+
const ok = await subtle.verify({ name: "RSASSA-PKCS1-v1_5" }, key, sigBytes, dataBytes);
|
|
225
|
+
if (!ok)
|
|
226
|
+
throw new Error("Signature mismatch.");
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/auth/admin/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { type SentroyAuthUser, type SignupResponse, type LoginResponse, type LoginOutcome, type SessionSummary, type ActivityEntry, type MfaStatus, type MfaEnrollResponse, type MfaVerifyEnrollmentResponse, type PasskeySummary, type SocialProvider } from "./types";
|
|
2
|
+
import { type AuthHttpOptions } from "./http";
|
|
3
|
+
/**
|
|
4
|
+
* Browser-facing Sentroy Auth SDK — Firebase Auth tarzı session API.
|
|
5
|
+
*
|
|
6
|
+
* `apiKey` BROWSER'DA OLMAMALI; bu sınıf `apiKey`'i header'a koyacaktır.
|
|
7
|
+
* RP backend gerçek api-key tutar; browser'da end-user kendi access/refresh
|
|
8
|
+
* token'larıyla yaşar. Yine de DX için sınıf hem apiKey-less browser
|
|
9
|
+
* akışına (signup/login backend proxy üzerinden) hem apiKey'li server
|
|
10
|
+
* akışına (admin) tek tip API sunar — caller hangi mod'da olduğunu
|
|
11
|
+
* `SentroyAuthAdmin` (admin SDK, sunucu) vs `SentroyAuth` (browser SDK,
|
|
12
|
+
* apiKey-less) seçimiyle netleştirir.
|
|
13
|
+
*
|
|
14
|
+
* Storage: browser'da access + refresh `storage` adapter'a yazılır
|
|
15
|
+
* (default `localStorage`). Refresh expire'a 5dk kala arka planda
|
|
16
|
+
* yenilenir; fail olursa `onAuthStateChanged(null)` ve storage silinir.
|
|
17
|
+
*
|
|
18
|
+
* **Server-side rendering**: `typeof window === "undefined"` korumalı —
|
|
19
|
+
* Node ortamında `localStorage` yok, default `memory` storage'a düşer.
|
|
20
|
+
*/
|
|
21
|
+
export type AuthStateChangeListener = (user: SentroyAuthUser | null) => void;
|
|
22
|
+
export interface AuthStorageAdapter {
|
|
23
|
+
read(): {
|
|
24
|
+
accessToken: string;
|
|
25
|
+
refreshToken: string;
|
|
26
|
+
user: SentroyAuthUser;
|
|
27
|
+
} | null;
|
|
28
|
+
write(value: {
|
|
29
|
+
accessToken: string;
|
|
30
|
+
refreshToken: string;
|
|
31
|
+
user: SentroyAuthUser;
|
|
32
|
+
}): void;
|
|
33
|
+
clear(): void;
|
|
34
|
+
}
|
|
35
|
+
export interface SentroyAuthOptions extends AuthHttpOptions {
|
|
36
|
+
/** Token persistence stratejisi. Default `"localStorage"` browser'da,
|
|
37
|
+
* Node'da otomatik `"memory"`. Custom için adapter geçilebilir. */
|
|
38
|
+
storage?: "localStorage" | "memory" | AuthStorageAdapter;
|
|
39
|
+
/** Background refresh tetikleme süresi (saniye, expiresIn altında).
|
|
40
|
+
* Default 300 (5dk). */
|
|
41
|
+
refreshSkew?: number;
|
|
42
|
+
}
|
|
43
|
+
export declare class SentroyAuth {
|
|
44
|
+
private readonly http;
|
|
45
|
+
private readonly storage;
|
|
46
|
+
private readonly listeners;
|
|
47
|
+
private readonly refreshSkew;
|
|
48
|
+
private refreshTimer;
|
|
49
|
+
private currentUser;
|
|
50
|
+
constructor(opts: SentroyAuthOptions);
|
|
51
|
+
get user(): SentroyAuthUser | null;
|
|
52
|
+
get accessToken(): string | null;
|
|
53
|
+
signUp(input: {
|
|
54
|
+
email: string;
|
|
55
|
+
password: string;
|
|
56
|
+
displayName?: string;
|
|
57
|
+
metadata?: Record<string, unknown>;
|
|
58
|
+
}): Promise<SignupResponse>;
|
|
59
|
+
/**
|
|
60
|
+
* Sign in with email/password. MFA enrolled user'lar için response
|
|
61
|
+
* discriminated union: `kind: "mfa"` → caller `verifyMfa()` çağırır.
|
|
62
|
+
* `kind: "tokens"` → session kuruldu.
|
|
63
|
+
*/
|
|
64
|
+
signIn(input: {
|
|
65
|
+
email: string;
|
|
66
|
+
password: string;
|
|
67
|
+
rememberMe?: boolean;
|
|
68
|
+
}): Promise<LoginOutcome>;
|
|
69
|
+
/**
|
|
70
|
+
* MFA verify — `signIn` ile `kind: "mfa"` döndüyse, kullanıcıdan code
|
|
71
|
+
* (veya recovery code) alıp bu method'u çağır. Başarılıysa session
|
|
72
|
+
* kurulur ve login tamamlanır.
|
|
73
|
+
*/
|
|
74
|
+
verifyMfa(input: {
|
|
75
|
+
mfaToken: string;
|
|
76
|
+
code?: string;
|
|
77
|
+
recoveryCode?: string;
|
|
78
|
+
}): Promise<LoginResponse>;
|
|
79
|
+
signOut(): Promise<void>;
|
|
80
|
+
sendPasswordReset(email: string): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Reset password using token from email. `newPassword` policy +
|
|
83
|
+
* HaveIBeenPwned breach check yapılır.
|
|
84
|
+
*/
|
|
85
|
+
confirmPasswordReset(input: {
|
|
86
|
+
token: string;
|
|
87
|
+
newPassword: string;
|
|
88
|
+
}): Promise<SentroyAuthUser>;
|
|
89
|
+
verifyEmail(token: string): Promise<SentroyAuthUser>;
|
|
90
|
+
/**
|
|
91
|
+
* Email magic-link request. Project'in `magicLinkEnabled` true
|
|
92
|
+
* olması gerekir. Uniform 200 response — email yoksa da hata vermez.
|
|
93
|
+
*/
|
|
94
|
+
sendMagicLink(input: {
|
|
95
|
+
email: string;
|
|
96
|
+
redirectUri?: string;
|
|
97
|
+
}): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Magic link mail'inden gelen token ile login. Session kurulur.
|
|
100
|
+
*/
|
|
101
|
+
consumeMagicLink(token: string): Promise<LoginResponse>;
|
|
102
|
+
/**
|
|
103
|
+
* Accept admin invitation. Token mail'den gelir, kullanıcı password
|
|
104
|
+
* + optional displayName girer; hesap create + session kurulur.
|
|
105
|
+
*/
|
|
106
|
+
acceptInvitation(input: {
|
|
107
|
+
token: string;
|
|
108
|
+
password: string;
|
|
109
|
+
displayName?: string;
|
|
110
|
+
}): Promise<LoginResponse>;
|
|
111
|
+
/**
|
|
112
|
+
* Provider authorize URL üret. `window.location.assign(url)` ile
|
|
113
|
+
* RP'nin sayfasından redirect — callback'te Sentroy session kurulur,
|
|
114
|
+
* redirectUri fragment'ında token'lar döner.
|
|
115
|
+
*/
|
|
116
|
+
socialAuthorizeUrl(provider: SocialProvider, opts?: {
|
|
117
|
+
redirectUri?: string;
|
|
118
|
+
rememberMe?: boolean;
|
|
119
|
+
}): string;
|
|
120
|
+
/**
|
|
121
|
+
* `window.location.hash`tan social login redirect sonrası gelen
|
|
122
|
+
* `#access_token=...&refresh_token=...&token_type=Bearer` parse +
|
|
123
|
+
* session kur. RP sayfasına redirectUri varsayılan akış kullanıldıysa
|
|
124
|
+
* çağırın. Başarılıysa user döner, fail'da null.
|
|
125
|
+
*/
|
|
126
|
+
consumeRedirectFragment(): Promise<SentroyAuthUser | null>;
|
|
127
|
+
getCurrentUser(): Promise<SentroyAuthUser | null>;
|
|
128
|
+
private fetchMe;
|
|
129
|
+
listSessions(): Promise<SessionSummary[]>;
|
|
130
|
+
revokeSession(id: string): Promise<void>;
|
|
131
|
+
/**
|
|
132
|
+
* Change password. Backend tüm session'ları revoke eder; SDK local
|
|
133
|
+
* session'ı temizler — caller `signIn` ile tekrar oturum açar.
|
|
134
|
+
*/
|
|
135
|
+
changePassword(input: {
|
|
136
|
+
currentPassword: string;
|
|
137
|
+
newPassword: string;
|
|
138
|
+
}): Promise<void>;
|
|
139
|
+
/**
|
|
140
|
+
* Request email change — confirmation mail yeni adrese gönderilir.
|
|
141
|
+
* Kullanıcı `confirmEmailChange(token)` ile finalize eder.
|
|
142
|
+
*/
|
|
143
|
+
requestEmailChange(input: {
|
|
144
|
+
newEmail: string;
|
|
145
|
+
currentPassword: string;
|
|
146
|
+
}): Promise<void>;
|
|
147
|
+
/** Token-based confirm (mail link'inden gelir). */
|
|
148
|
+
confirmEmailChange(token: string): Promise<SentroyAuthUser>;
|
|
149
|
+
requestAccountDeletion(currentPassword: string): Promise<void>;
|
|
150
|
+
confirmAccountDeletion(token: string): Promise<void>;
|
|
151
|
+
getActivity(): Promise<ActivityEntry[]>;
|
|
152
|
+
readonly mfa: {
|
|
153
|
+
getStatus: () => Promise<MfaStatus>;
|
|
154
|
+
enrollTotp: () => Promise<MfaEnrollResponse>;
|
|
155
|
+
verifyTotpEnrollment: (code: string) => Promise<MfaVerifyEnrollmentResponse>;
|
|
156
|
+
disableTotp: (currentPassword: string) => Promise<void>;
|
|
157
|
+
};
|
|
158
|
+
readonly passkey: {
|
|
159
|
+
list: () => Promise<PasskeySummary[]>;
|
|
160
|
+
delete: (id: string) => Promise<void>;
|
|
161
|
+
/**
|
|
162
|
+
* Register a new passkey on this device.
|
|
163
|
+
*
|
|
164
|
+
* Browser-only: dynamically imports `@simplewebauthn/browser`. RP
|
|
165
|
+
* SDK kullanıyor ama webauthn/browser bağımlılığı yoksa caller
|
|
166
|
+
* `peerDependencies` aracılığıyla manuel ekler.
|
|
167
|
+
*/
|
|
168
|
+
register: (deviceName?: string) => Promise<void>;
|
|
169
|
+
/**
|
|
170
|
+
* Sign in with passkey. Email opsiyonel — verilirse server o
|
|
171
|
+
* user'ın passkey'lerini allowList yapar, yoksa "usernameless".
|
|
172
|
+
* Session kurulur.
|
|
173
|
+
*/
|
|
174
|
+
authenticate: (opts?: {
|
|
175
|
+
email?: string;
|
|
176
|
+
rememberMe?: boolean;
|
|
177
|
+
}) => Promise<LoginResponse>;
|
|
178
|
+
};
|
|
179
|
+
/**
|
|
180
|
+
* Force refresh now — caller'ın sürdüğü access token süresi dolmuş
|
|
181
|
+
* olabilir; bu method yeni token'ları persist eder.
|
|
182
|
+
*/
|
|
183
|
+
refreshNow(): Promise<void>;
|
|
184
|
+
/** Manual session injection — fragment / cookie redirect dışında tokens
|
|
185
|
+
* başka bir kanaldan elde edildiyse (örn. RP custom auth callback). */
|
|
186
|
+
setSession(input: {
|
|
187
|
+
accessToken: string;
|
|
188
|
+
refreshToken: string;
|
|
189
|
+
user: SentroyAuthUser;
|
|
190
|
+
}): void;
|
|
191
|
+
private requireToken;
|
|
192
|
+
/**
|
|
193
|
+
* Subscription pattern — Firebase Auth uyumlu. Caller'ın hemen mevcut
|
|
194
|
+
* state'i alabilmesi için constructor'da restore edilen user
|
|
195
|
+
* subscribe sırasında bir kez dispatch edilir.
|
|
196
|
+
*/
|
|
197
|
+
onAuthStateChanged(listener: AuthStateChangeListener): () => void;
|
|
198
|
+
private persist;
|
|
199
|
+
private clearSession;
|
|
200
|
+
private notify;
|
|
201
|
+
/**
|
|
202
|
+
* JWT'nin `exp` claim'inden expiry'i tahmin et. Parsing fail ise
|
|
203
|
+
* 1 saat varsay (default access TTL). Refresh window: exp - skew.
|
|
204
|
+
*
|
|
205
|
+
* **Browser-safe**: `Buffer` Node'a özel, tarayıcıda yok. `atob`
|
|
206
|
+
* + URL-safe charset normalization ile decode ediyoruz.
|
|
207
|
+
*/
|
|
208
|
+
private estimateExpiry;
|
|
209
|
+
private scheduleRefresh;
|
|
210
|
+
private refresh;
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/auth/client.ts"],"names":[],"mappings":"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"}
|