@atzentis/auth-sdk 0.0.7 → 0.0.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/index.d.ts CHANGED
@@ -62,6 +62,125 @@ declare class HttpClient {
62
62
  private executeFetch;
63
63
  }
64
64
 
65
+ interface Device {
66
+ id: string;
67
+ name: string;
68
+ deviceType: "mobile" | "desktop" | "tablet";
69
+ browser: string;
70
+ os: string;
71
+ isTrusted: boolean;
72
+ isCurrent: boolean;
73
+ lastUsedAt: string;
74
+ lastIp: string;
75
+ lastCity?: string;
76
+ lastCountry?: string;
77
+ createdAt: string;
78
+ }
79
+ interface ListDevicesResponse {
80
+ data: Device[];
81
+ total: number;
82
+ }
83
+ interface RemoveAllOtherDevicesResponse {
84
+ removedCount: number;
85
+ }
86
+ declare const RISK_LEVEL_NONE = 0;
87
+ declare const RISK_LEVEL_LOW = 30;
88
+ declare const RISK_LEVEL_MEDIUM = 60;
89
+ declare const RISK_LEVEL_HIGH = 80;
90
+ type RiskLevel = "none" | "low" | "medium" | "high";
91
+ declare function getRiskLevel(score: number): RiskLevel;
92
+
93
+ declare class DeviceService {
94
+ private readonly httpClient;
95
+ constructor(httpClient: HttpClient);
96
+ list(): Promise<ListDevicesResponse>;
97
+ getCurrent(): Promise<Device>;
98
+ trust(deviceId: string): Promise<void>;
99
+ untrust(deviceId: string): Promise<void>;
100
+ remove(deviceId: string): Promise<void>;
101
+ removeAllOthers(): Promise<RemoveAllOtherDevicesResponse>;
102
+ }
103
+
104
+ type OrganizationRole = "owner" | "admin" | "member";
105
+ type InvitationStatus = "pending" | "accepted" | "declined" | "expired";
106
+ interface Organization {
107
+ id: string;
108
+ name: string;
109
+ slug: string;
110
+ logo?: string;
111
+ createdAt: string;
112
+ metadata?: Record<string, unknown>;
113
+ }
114
+ interface CreateOrganizationRequest {
115
+ name: string;
116
+ slug?: string;
117
+ logo?: string;
118
+ }
119
+ interface UpdateOrganizationRequest {
120
+ name?: string;
121
+ slug?: string;
122
+ logo?: string;
123
+ metadata?: Record<string, unknown>;
124
+ }
125
+ interface ListOrganizationsRequest {
126
+ limit?: number;
127
+ offset?: number;
128
+ }
129
+ interface ListOrganizationsResponse {
130
+ data: Organization[];
131
+ total: number;
132
+ limit: number;
133
+ offset: number;
134
+ }
135
+ interface Member {
136
+ userId: string;
137
+ user: User;
138
+ role: OrganizationRole;
139
+ joinedAt: string;
140
+ }
141
+ interface ListMembersRequest {
142
+ limit?: number;
143
+ offset?: number;
144
+ }
145
+ interface ListMembersResponse {
146
+ data: Member[];
147
+ total: number;
148
+ limit: number;
149
+ offset: number;
150
+ }
151
+ interface UpdateMemberRequest {
152
+ role: OrganizationRole;
153
+ }
154
+ interface Invitation {
155
+ id: string;
156
+ email: string;
157
+ role: OrganizationRole;
158
+ status: InvitationStatus;
159
+ expiresAt: string;
160
+ invitedBy: string;
161
+ createdAt: string;
162
+ }
163
+ interface InviteMemberRequest {
164
+ email: string;
165
+ role: OrganizationRole;
166
+ }
167
+ interface AcceptInvitationRequest {
168
+ token: string;
169
+ }
170
+ interface DeclineInvitationRequest {
171
+ token: string;
172
+ }
173
+ interface ListInvitationsRequest {
174
+ limit?: number;
175
+ offset?: number;
176
+ }
177
+ interface ListInvitationsResponse {
178
+ data: Invitation[];
179
+ total: number;
180
+ limit: number;
181
+ offset: number;
182
+ }
183
+
65
184
  interface User {
66
185
  id: string;
67
186
  email: string;
@@ -78,12 +197,6 @@ interface User {
78
197
  updatedAt?: string;
79
198
  lastLoginAt?: string;
80
199
  }
81
- interface Organization {
82
- id: string;
83
- name: string;
84
- slug: string;
85
- logo?: string;
86
- }
87
200
 
88
201
  interface LoginCredentials {
89
202
  email: string;
@@ -200,11 +313,61 @@ interface LoginEvent {
200
313
  createdAt: string;
201
314
  }
202
315
  interface LoginAlert {
316
+ eventId: string;
203
317
  deviceName: string;
204
318
  deviceType: "mobile" | "desktop" | "tablet";
205
319
  city?: string;
206
320
  country?: string;
207
321
  riskScore: number;
322
+ method: string;
323
+ timestamp: string;
324
+ }
325
+
326
+ interface ListLoginEventsRequest {
327
+ limit?: number;
328
+ offset?: number;
329
+ status?: "success" | "failed" | "blocked";
330
+ dateFrom?: string;
331
+ dateTo?: string;
332
+ }
333
+ interface ListLoginEventsResponse {
334
+ data: LoginEvent[];
335
+ total: number;
336
+ limit: number;
337
+ offset: number;
338
+ }
339
+ interface ReportSuspiciousResponse {
340
+ success: boolean;
341
+ sessionRevoked: boolean;
342
+ passwordResetSent: boolean;
343
+ }
344
+
345
+ declare class LoginActivityService {
346
+ private readonly httpClient;
347
+ constructor(httpClient: HttpClient);
348
+ list(options?: ListLoginEventsRequest): Promise<ListLoginEventsResponse>;
349
+ markRecognized(eventId: string): Promise<void>;
350
+ reportSuspicious(eventId: string): Promise<ReportSuspiciousResponse>;
351
+ }
352
+
353
+ declare class OrganizationService {
354
+ private readonly httpClient;
355
+ constructor(httpClient: HttpClient);
356
+ getCurrent(): Promise<Organization>;
357
+ list(options?: ListOrganizationsRequest): Promise<ListOrganizationsResponse>;
358
+ create(data: CreateOrganizationRequest): Promise<Organization>;
359
+ update(orgId: string, data: UpdateOrganizationRequest): Promise<Organization>;
360
+ delete(orgId: string): Promise<void>;
361
+ listMembers(orgId: string, options?: ListMembersRequest): Promise<ListMembersResponse>;
362
+ updateMember(orgId: string, userId: string, data: UpdateMemberRequest): Promise<Member>;
363
+ removeMember(orgId: string, userId: string): Promise<void>;
364
+ inviteMember(orgId: string, data: InviteMemberRequest): Promise<Invitation>;
365
+ acceptInvitation(data: AcceptInvitationRequest): Promise<Organization>;
366
+ declineInvitation(data: DeclineInvitationRequest): Promise<void>;
367
+ listInvitations(orgId: string, options?: ListInvitationsRequest): Promise<ListInvitationsResponse>;
368
+ resendInvitation(orgId: string, invitationId: string): Promise<void>;
369
+ cancelInvitation(orgId: string, invitationId: string): Promise<void>;
370
+ leave(orgId: string): Promise<void>;
208
371
  }
209
372
 
210
373
  interface SendOTPRequest {
@@ -344,6 +507,9 @@ declare class AuthClient {
344
507
  private readonly storage;
345
508
  private readonly authService;
346
509
  private readonly backgroundRefresh;
510
+ readonly devices: DeviceService;
511
+ readonly loginActivity: LoginActivityService;
512
+ readonly organizations: OrganizationService;
347
513
  readonly phone: PhoneService;
348
514
  readonly sessions: SessionService;
349
515
  constructor(config: AuthConfig);
@@ -617,4 +783,4 @@ declare class MemoryStorage implements ITokenStorage {
617
783
  remove(key: string): Promise<void>;
618
784
  }
619
785
 
620
- export { type ApiResponse, AuthClient, type AuthConfig, AuthError, AuthErrorCode, type AuthErrorOptions, type AuthInterceptorConfig, AuthService, AuthenticationError, BackgroundRefresh, BrowserDeviceSignalCollector, ConflictError, CookieStorage, type CookieStorageOptions, DEFAULT_LAST_LOGIN_METHOD_KEY, DEFAULT_REFRESH_TOKEN_STORAGE_KEY, DEFAULT_SESSION_STORAGE_KEY, DEFAULT_TOKEN_STORAGE_KEY, type DecodedToken, type DeviceSession, type DeviceSignals, type DeviceSummary, type ErrorInterceptor, ForbiddenError, type GetOAuthUrlRequest, HttpClient, type HttpClientConfig, type HttpMethod, type IDeviceSignalCollector, type ITokenStorage, type ListSessionsRequest, type ListSessionsResponse, LocalStorageAdapter, type LoginAlert, type LoginCredentials, type LoginEvent, type LoginResponse, MemoryStorage, NetworkError, NotFoundError, type OAuthProvider, type Organization, PhoneService, type PhoneSignInRequest, type RateLimitConfig, RateLimitError, type RefreshTokenResponse, type RequestConfig, type RequestInterceptor, type RequestPasswordResetRequest, type ResetPasswordRequest, type ResetPasswordResponse, type ResponseInterceptor, type RetryConfig, type RevokeAllSessionsOptions, type RevokeAllSessionsResponse, type SendMagicLinkRequest, type SendOTPRequest, type SendOTPResponse, type SendVerificationEmailRequest, ServerError, type Session, SessionService, type SetActiveSessionRequest, type SetActiveSessionResponse, type SignupData, type SignupResponse, TimeoutError, UnprocessableError, type User, type UsernameLoginCredentials, ValidationError, type VerifyEmailRequest, type VerifyEmailResponse, type VerifyMagicLinkRequest, type VerifyOAuthCodeRequest, type VerifyOAuthCodeResponse, type VerifyOTPRequest, type VerifyOTPResponse, createAuthInterceptor, createDeviceSignalInterceptor, createErrorFromResponse, decodeJwtPayload, hasDevice, validatePhoneNumber, validateUsername };
786
+ export { type AcceptInvitationRequest, type ApiResponse, AuthClient, type AuthConfig, AuthError, AuthErrorCode, type AuthErrorOptions, type AuthInterceptorConfig, AuthService, AuthenticationError, BackgroundRefresh, BrowserDeviceSignalCollector, ConflictError, CookieStorage, type CookieStorageOptions, type CreateOrganizationRequest, DEFAULT_LAST_LOGIN_METHOD_KEY, DEFAULT_REFRESH_TOKEN_STORAGE_KEY, DEFAULT_SESSION_STORAGE_KEY, DEFAULT_TOKEN_STORAGE_KEY, type DeclineInvitationRequest, type DecodedToken, type Device, DeviceService, type DeviceSession, type DeviceSignals, type DeviceSummary, type ErrorInterceptor, ForbiddenError, type GetOAuthUrlRequest, HttpClient, type HttpClientConfig, type HttpMethod, type IDeviceSignalCollector, type ITokenStorage, type Invitation, type InvitationStatus, type InviteMemberRequest, type ListDevicesResponse, type ListInvitationsRequest, type ListInvitationsResponse, type ListLoginEventsRequest, type ListLoginEventsResponse, type ListMembersRequest, type ListMembersResponse, type ListOrganizationsRequest, type ListOrganizationsResponse, type ListSessionsRequest, type ListSessionsResponse, LocalStorageAdapter, LoginActivityService, type LoginAlert, type LoginCredentials, type LoginEvent, type LoginResponse, type Member, MemoryStorage, NetworkError, NotFoundError, type OAuthProvider, type Organization, type OrganizationRole, OrganizationService, PhoneService, type PhoneSignInRequest, RISK_LEVEL_HIGH, RISK_LEVEL_LOW, RISK_LEVEL_MEDIUM, RISK_LEVEL_NONE, type RateLimitConfig, RateLimitError, type RefreshTokenResponse, type RemoveAllOtherDevicesResponse, type ReportSuspiciousResponse, type RequestConfig, type RequestInterceptor, type RequestPasswordResetRequest, type ResetPasswordRequest, type ResetPasswordResponse, type ResponseInterceptor, type RetryConfig, type RevokeAllSessionsOptions, type RevokeAllSessionsResponse, type RiskLevel, type SendMagicLinkRequest, type SendOTPRequest, type SendOTPResponse, type SendVerificationEmailRequest, ServerError, type Session, SessionService, type SetActiveSessionRequest, type SetActiveSessionResponse, type SignupData, type SignupResponse, TimeoutError, UnprocessableError, type UpdateMemberRequest, type UpdateOrganizationRequest, type User, type UsernameLoginCredentials, ValidationError, type VerifyEmailRequest, type VerifyEmailResponse, type VerifyMagicLinkRequest, type VerifyOAuthCodeRequest, type VerifyOAuthCodeResponse, type VerifyOTPRequest, type VerifyOTPResponse, createAuthInterceptor, createDeviceSignalInterceptor, createErrorFromResponse, decodeJwtPayload, getRiskLevel, hasDevice, validatePhoneNumber, validateUsername };
package/dist/index.js CHANGED
@@ -520,7 +520,7 @@ var AuthService = class {
520
520
  this.sessionStorageKey = options?.sessionStorageKey ?? DEFAULT_SESSION_STORAGE_KEY;
521
521
  this.lastLoginMethodKey = options?.lastLoginMethodKey ?? DEFAULT_LAST_LOGIN_METHOD_KEY;
522
522
  }
523
- // --- Email/Password Login & Signup (T02-001) ---
523
+ // --- Email/Password Login & Signup ---
524
524
  async login(credentials) {
525
525
  const { data } = await this.httpClient.post("/auth/login", credentials, {
526
526
  skipAuth: true
@@ -537,7 +537,7 @@ var AuthService = class {
537
537
  await this.setLastLoginMethod("email");
538
538
  return response;
539
539
  }
540
- // --- Username Login (T02-002) ---
540
+ // --- Username Login ---
541
541
  async loginWithUsername(credentials) {
542
542
  validateUsername(credentials.username);
543
543
  const { data } = await this.httpClient.post(
@@ -556,7 +556,7 @@ var AuthService = class {
556
556
  });
557
557
  return data.available;
558
558
  }
559
- // --- OAuth (T02-004) ---
559
+ // --- OAuth ---
560
560
  getOAuthUrl(request) {
561
561
  const baseUrl = this.httpClient.getBaseUrl();
562
562
  const params = new URLSearchParams({
@@ -577,7 +577,7 @@ var AuthService = class {
577
577
  await this.setLastLoginMethod("oauth");
578
578
  return data;
579
579
  }
580
- // --- Magic Link (T02-005) ---
580
+ // --- Magic Link ---
581
581
  async sendMagicLink(request) {
582
582
  await this.httpClient.post("/auth/magic-link/send", request, { skipAuth: true });
583
583
  }
@@ -589,7 +589,7 @@ var AuthService = class {
589
589
  await this.setLastLoginMethod("magic_link");
590
590
  return data;
591
591
  }
592
- // --- Email Verification (T02-006) ---
592
+ // --- Email Verification ---
593
593
  async sendVerificationEmail(request) {
594
594
  await this.httpClient.post("/auth/email/send-verification", request);
595
595
  }
@@ -601,7 +601,7 @@ var AuthService = class {
601
601
  );
602
602
  return data;
603
603
  }
604
- // --- Password Reset (T02-007) ---
604
+ // --- Password Reset ---
605
605
  async requestPasswordReset(request) {
606
606
  await this.httpClient.post("/auth/password/reset-request", request, { skipAuth: true });
607
607
  }
@@ -613,7 +613,7 @@ var AuthService = class {
613
613
  );
614
614
  return data;
615
615
  }
616
- // --- Token Management (T02-009) ---
616
+ // --- Token Management ---
617
617
  async getAccessToken() {
618
618
  return this.storage.get(this.tokenStorageKey);
619
619
  }
@@ -638,7 +638,7 @@ var AuthService = class {
638
638
  async getLastLoginMethod() {
639
639
  return this.storage.get(this.lastLoginMethodKey);
640
640
  }
641
- // --- Logout (T02-010) ---
641
+ // --- Logout ---
642
642
  async logout() {
643
643
  try {
644
644
  await this.httpClient.post("/auth/logout", {});
@@ -691,6 +691,197 @@ function decodeJwtPayload(token) {
691
691
  }
692
692
  }
693
693
 
694
+ // src/services/device.ts
695
+ var DeviceService = class {
696
+ httpClient;
697
+ constructor(httpClient) {
698
+ this.httpClient = httpClient;
699
+ }
700
+ async list() {
701
+ const { data } = await this.httpClient.get("/auth/devices");
702
+ return data;
703
+ }
704
+ async getCurrent() {
705
+ const { data } = await this.httpClient.get("/auth/devices/current");
706
+ return data;
707
+ }
708
+ async trust(deviceId) {
709
+ await this.httpClient.post(`/auth/devices/${deviceId}/trust`);
710
+ }
711
+ async untrust(deviceId) {
712
+ await this.httpClient.post(`/auth/devices/${deviceId}/untrust`);
713
+ }
714
+ async remove(deviceId) {
715
+ await this.httpClient.delete(`/auth/devices/${deviceId}`);
716
+ }
717
+ async removeAllOthers() {
718
+ const { data } = await this.httpClient.post(
719
+ "/auth/devices/remove-all-others"
720
+ );
721
+ return data;
722
+ }
723
+ };
724
+
725
+ // src/services/login-activity.ts
726
+ var LoginActivityService = class {
727
+ httpClient;
728
+ constructor(httpClient) {
729
+ this.httpClient = httpClient;
730
+ }
731
+ async list(options) {
732
+ const params = {};
733
+ if (options?.limit !== void 0) params.limit = options.limit;
734
+ if (options?.offset !== void 0) params.offset = options.offset;
735
+ if (options?.status !== void 0) params.status = options.status;
736
+ if (options?.dateFrom !== void 0) params.dateFrom = options.dateFrom;
737
+ if (options?.dateTo !== void 0) params.dateTo = options.dateTo;
738
+ const { data } = await this.httpClient.get("/auth/login-activity", {
739
+ params
740
+ });
741
+ return data;
742
+ }
743
+ async markRecognized(eventId) {
744
+ await this.httpClient.post(`/auth/login-activity/${eventId}/recognize`);
745
+ }
746
+ async reportSuspicious(eventId) {
747
+ const { data } = await this.httpClient.post(
748
+ `/auth/login-activity/${eventId}/report`
749
+ );
750
+ return data;
751
+ }
752
+ };
753
+
754
+ // src/services/organization.ts
755
+ var OrganizationService = class {
756
+ httpClient;
757
+ constructor(httpClient) {
758
+ this.httpClient = httpClient;
759
+ }
760
+ // --- Organization CRUD ---
761
+ async getCurrent() {
762
+ const { data } = await this.httpClient.get("/organizations/current");
763
+ return data;
764
+ }
765
+ async list(options) {
766
+ const params = new URLSearchParams();
767
+ if (options?.limit !== void 0) params.set("limit", String(options.limit));
768
+ if (options?.offset !== void 0) params.set("offset", String(options.offset));
769
+ const query = params.toString();
770
+ const path = query ? `/organizations?${query}` : "/organizations";
771
+ const { data } = await this.httpClient.get(path);
772
+ return data;
773
+ }
774
+ async create(data) {
775
+ const { data: result } = await this.httpClient.post("/organizations", data);
776
+ return result;
777
+ }
778
+ async update(orgId, data) {
779
+ const { data: result } = await this.httpClient.patch(
780
+ `/organizations/${orgId}`,
781
+ data
782
+ );
783
+ return result;
784
+ }
785
+ async delete(orgId) {
786
+ await this.httpClient.delete(`/organizations/${orgId}`);
787
+ }
788
+ // --- Member Management ---
789
+ async listMembers(orgId, options) {
790
+ const params = new URLSearchParams();
791
+ if (options?.limit !== void 0) params.set("limit", String(options.limit));
792
+ if (options?.offset !== void 0) params.set("offset", String(options.offset));
793
+ const query = params.toString();
794
+ const path = query ? `/organizations/${orgId}/members?${query}` : `/organizations/${orgId}/members`;
795
+ const { data } = await this.httpClient.get(path);
796
+ return data;
797
+ }
798
+ async updateMember(orgId, userId, data) {
799
+ const { data: result } = await this.httpClient.patch(
800
+ `/organizations/${orgId}/members/${userId}`,
801
+ data
802
+ );
803
+ return result;
804
+ }
805
+ async removeMember(orgId, userId) {
806
+ await this.httpClient.delete(`/organizations/${orgId}/members/${userId}`);
807
+ }
808
+ // --- Invitation Flow ---
809
+ async inviteMember(orgId, data) {
810
+ const { data: result } = await this.httpClient.post(
811
+ `/organizations/${orgId}/invitations`,
812
+ data
813
+ );
814
+ return result;
815
+ }
816
+ async acceptInvitation(data) {
817
+ const { data: result } = await this.httpClient.post(
818
+ "/organizations/invitations/accept",
819
+ data
820
+ );
821
+ return result;
822
+ }
823
+ async declineInvitation(data) {
824
+ await this.httpClient.post("/organizations/invitations/decline", data);
825
+ }
826
+ // --- Invitation Management ---
827
+ async listInvitations(orgId, options) {
828
+ const params = new URLSearchParams();
829
+ if (options?.limit !== void 0) params.set("limit", String(options.limit));
830
+ if (options?.offset !== void 0) params.set("offset", String(options.offset));
831
+ const query = params.toString();
832
+ const path = query ? `/organizations/${orgId}/invitations?${query}` : `/organizations/${orgId}/invitations`;
833
+ const { data } = await this.httpClient.get(path);
834
+ return data;
835
+ }
836
+ async resendInvitation(orgId, invitationId) {
837
+ await this.httpClient.post(`/organizations/${orgId}/invitations/${invitationId}/resend`);
838
+ }
839
+ async cancelInvitation(orgId, invitationId) {
840
+ await this.httpClient.delete(`/organizations/${orgId}/invitations/${invitationId}`);
841
+ }
842
+ // --- Organization Leave ---
843
+ async leave(orgId) {
844
+ await this.httpClient.post(`/organizations/${orgId}/leave`);
845
+ }
846
+ };
847
+
848
+ // src/services/phone.ts
849
+ var PhoneService = class {
850
+ httpClient;
851
+ storeTokensFn;
852
+ setLastLoginMethodFn;
853
+ constructor(httpClient, storeTokens, setLastLoginMethod) {
854
+ this.httpClient = httpClient;
855
+ this.storeTokensFn = storeTokens;
856
+ this.setLastLoginMethodFn = setLastLoginMethod;
857
+ }
858
+ async sendOTP(request) {
859
+ validatePhoneNumber(request.phoneNumber);
860
+ const { data } = await this.httpClient.post("/auth/phone/send-otp", request, {
861
+ skipAuth: true
862
+ });
863
+ return data;
864
+ }
865
+ async verify(request) {
866
+ validatePhoneNumber(request.phoneNumber);
867
+ const { data } = await this.httpClient.post("/auth/phone/verify", request, {
868
+ skipAuth: true
869
+ });
870
+ await this.storeTokensFn(data.accessToken, data.refreshToken);
871
+ await this.setLastLoginMethodFn("phone");
872
+ return data;
873
+ }
874
+ async signIn(request) {
875
+ validatePhoneNumber(request.phoneNumber);
876
+ const { data } = await this.httpClient.post("/auth/phone/sign-in", request, {
877
+ skipAuth: true
878
+ });
879
+ await this.storeTokensFn(data.accessToken, data.refreshToken);
880
+ await this.setLastLoginMethodFn("phone");
881
+ return data;
882
+ }
883
+ };
884
+
694
885
  // src/services/refresh.ts
695
886
  var BackgroundRefresh = class {
696
887
  constructor(refreshFn, threshold, callbacks = {}) {
@@ -746,43 +937,6 @@ var BackgroundRefresh = class {
746
937
  }
747
938
  };
748
939
 
749
- // src/services/phone.ts
750
- var PhoneService = class {
751
- httpClient;
752
- storeTokensFn;
753
- setLastLoginMethodFn;
754
- constructor(httpClient, storeTokens, setLastLoginMethod) {
755
- this.httpClient = httpClient;
756
- this.storeTokensFn = storeTokens;
757
- this.setLastLoginMethodFn = setLastLoginMethod;
758
- }
759
- async sendOTP(request) {
760
- validatePhoneNumber(request.phoneNumber);
761
- const { data } = await this.httpClient.post("/auth/phone/send-otp", request, {
762
- skipAuth: true
763
- });
764
- return data;
765
- }
766
- async verify(request) {
767
- validatePhoneNumber(request.phoneNumber);
768
- const { data } = await this.httpClient.post("/auth/phone/verify", request, {
769
- skipAuth: true
770
- });
771
- await this.storeTokensFn(data.accessToken, data.refreshToken);
772
- await this.setLastLoginMethodFn("phone");
773
- return data;
774
- }
775
- async signIn(request) {
776
- validatePhoneNumber(request.phoneNumber);
777
- const { data } = await this.httpClient.post("/auth/phone/sign-in", request, {
778
- skipAuth: true
779
- });
780
- await this.storeTokensFn(data.accessToken, data.refreshToken);
781
- await this.setLastLoginMethodFn("phone");
782
- return data;
783
- }
784
- };
785
-
786
940
  // src/services/session.ts
787
941
  var SessionService = class {
788
942
  httpClient;
@@ -791,7 +945,7 @@ var SessionService = class {
791
945
  this.httpClient = httpClient;
792
946
  this.storeTokens = storeTokens;
793
947
  }
794
- // --- Session CRUD (T03-001) ---
948
+ // --- Session CRUD ---
795
949
  async getCurrent() {
796
950
  const { data } = await this.httpClient.get("/auth/sessions/current");
797
951
  return data;
@@ -806,7 +960,7 @@ var SessionService = class {
806
960
  async revoke(sessionId) {
807
961
  await this.httpClient.delete(`/auth/sessions/${sessionId}`);
808
962
  }
809
- // --- Revoke All (T03-002) ---
963
+ // --- Revoke All ---
810
964
  async revokeAll(options) {
811
965
  const { data } = await this.httpClient.post(
812
966
  "/auth/sessions/revoke-all",
@@ -814,7 +968,7 @@ var SessionService = class {
814
968
  );
815
969
  return data;
816
970
  }
817
- // --- Multi-Session (T03-003, T03-004) ---
971
+ // --- Multi-Session ---
818
972
  async listDeviceSessions() {
819
973
  const { data } = await this.httpClient.get("/auth/sessions/device");
820
974
  return data;
@@ -830,7 +984,7 @@ var SessionService = class {
830
984
  async revokeDeviceSession(request) {
831
985
  await this.httpClient.delete(`/auth/sessions/device/${request.sessionToken}`);
832
986
  }
833
- // --- Device Summary (T03-007) ---
987
+ // --- Device Summary ---
834
988
  async getCurrentDevice() {
835
989
  const session = await this.getCurrent();
836
990
  return session.device ?? null;
@@ -926,14 +1080,28 @@ var MemoryStorage = class {
926
1080
  }
927
1081
  };
928
1082
 
1083
+ // src/types/device.ts
1084
+ var RISK_LEVEL_NONE = 0;
1085
+ var RISK_LEVEL_LOW = 30;
1086
+ var RISK_LEVEL_MEDIUM = 60;
1087
+ var RISK_LEVEL_HIGH = 80;
1088
+ function getRiskLevel(score) {
1089
+ if (score >= RISK_LEVEL_HIGH) return "high";
1090
+ if (score >= RISK_LEVEL_MEDIUM) return "medium";
1091
+ if (score >= RISK_LEVEL_LOW) return "low";
1092
+ return "none";
1093
+ }
1094
+
929
1095
  // src/client.ts
930
- var RISK_ALERT_THRESHOLD = 30;
931
1096
  var AuthClient = class {
932
1097
  config;
933
1098
  httpClient;
934
1099
  storage;
935
1100
  authService;
936
1101
  backgroundRefresh;
1102
+ devices;
1103
+ loginActivity;
1104
+ organizations;
937
1105
  phone;
938
1106
  sessions;
939
1107
  constructor(config) {
@@ -974,6 +1142,9 @@ var AuthClient = class {
974
1142
  tokenStorageKey,
975
1143
  refreshTokenStorageKey
976
1144
  });
1145
+ this.devices = new DeviceService(this.httpClient);
1146
+ this.loginActivity = new LoginActivityService(this.httpClient);
1147
+ this.organizations = new OrganizationService(this.httpClient);
977
1148
  this.phone = new PhoneService(
978
1149
  this.httpClient,
979
1150
  (accessToken, refreshToken) => this.authService.storeTokens(accessToken, refreshToken),
@@ -995,7 +1166,7 @@ var AuthClient = class {
995
1166
  }
996
1167
  );
997
1168
  }
998
- // --- Email/Password (T02-001) ---
1169
+ // --- Email/Password ---
999
1170
  async login(credentials) {
1000
1171
  const response = await this.authService.login(credentials);
1001
1172
  this.handleLoginEvent(response);
@@ -1007,7 +1178,7 @@ var AuthClient = class {
1007
1178
  this.startRefreshIfEnabled(response.expiresIn);
1008
1179
  return response;
1009
1180
  }
1010
- // --- Username (T02-002) ---
1181
+ // --- Username ---
1011
1182
  async loginWithUsername(credentials) {
1012
1183
  const response = await this.authService.loginWithUsername(credentials);
1013
1184
  this.handleLoginEvent(response);
@@ -1017,7 +1188,7 @@ var AuthClient = class {
1017
1188
  async isUsernameAvailable(username) {
1018
1189
  return this.authService.isUsernameAvailable(username);
1019
1190
  }
1020
- // --- OAuth (T02-004) ---
1191
+ // --- OAuth ---
1021
1192
  getOAuthUrl(request) {
1022
1193
  return this.authService.getOAuthUrl(request);
1023
1194
  }
@@ -1027,7 +1198,7 @@ var AuthClient = class {
1027
1198
  this.startRefreshIfEnabled(response.expiresIn);
1028
1199
  return response;
1029
1200
  }
1030
- // --- Magic Link (T02-005) ---
1201
+ // --- Magic Link ---
1031
1202
  async sendMagicLink(request) {
1032
1203
  return this.authService.sendMagicLink(request);
1033
1204
  }
@@ -1037,21 +1208,21 @@ var AuthClient = class {
1037
1208
  this.startRefreshIfEnabled(response.expiresIn);
1038
1209
  return response;
1039
1210
  }
1040
- // --- Email Verification (T02-006) ---
1211
+ // --- Email Verification ---
1041
1212
  async sendVerificationEmail(request) {
1042
1213
  return this.authService.sendVerificationEmail(request);
1043
1214
  }
1044
1215
  async verifyEmail(request) {
1045
1216
  return this.authService.verifyEmail(request);
1046
1217
  }
1047
- // --- Password Reset (T02-007) ---
1218
+ // --- Password Reset ---
1048
1219
  async requestPasswordReset(request) {
1049
1220
  return this.authService.requestPasswordReset(request);
1050
1221
  }
1051
1222
  async resetPassword(request) {
1052
1223
  return this.authService.resetPassword(request);
1053
1224
  }
1054
- // --- Token Management (T02-009) ---
1225
+ // --- Token Management ---
1055
1226
  async getAccessToken() {
1056
1227
  return this.authService.getAccessToken();
1057
1228
  }
@@ -1064,7 +1235,7 @@ var AuthClient = class {
1064
1235
  async getLastLoginMethod() {
1065
1236
  return this.authService.getLastLoginMethod();
1066
1237
  }
1067
- // --- Logout (T02-010) ---
1238
+ // --- Logout ---
1068
1239
  async logout() {
1069
1240
  this.backgroundRefresh.stop();
1070
1241
  await this.authService.logout();
@@ -1082,14 +1253,17 @@ var AuthClient = class {
1082
1253
  }
1083
1254
  }
1084
1255
  handleLoginEvent(response) {
1085
- if (response.loginEvent && response.loginEvent.riskScore >= RISK_ALERT_THRESHOLD && this.config.onNewDeviceAlert) {
1256
+ if (response.loginEvent && response.loginEvent.riskScore >= RISK_LEVEL_LOW && this.config.onNewDeviceAlert) {
1086
1257
  const event = response.loginEvent;
1087
1258
  this.config.onNewDeviceAlert({
1259
+ eventId: event.id,
1088
1260
  deviceName: event.deviceName,
1089
1261
  deviceType: event.deviceType,
1090
1262
  city: event.city,
1091
1263
  country: event.country,
1092
- riskScore: event.riskScore
1264
+ riskScore: event.riskScore,
1265
+ method: event.method,
1266
+ timestamp: event.createdAt
1093
1267
  });
1094
1268
  }
1095
1269
  }
@@ -1142,6 +1316,6 @@ var AuthErrorCode = /* @__PURE__ */ ((AuthErrorCode2) => {
1142
1316
  return AuthErrorCode2;
1143
1317
  })(AuthErrorCode || {});
1144
1318
 
1145
- export { AuthClient, AuthError, AuthErrorCode, AuthService, AuthenticationError, BackgroundRefresh, BrowserDeviceSignalCollector, ConflictError, CookieStorage, DEFAULT_LAST_LOGIN_METHOD_KEY, DEFAULT_REFRESH_TOKEN_STORAGE_KEY, DEFAULT_SESSION_STORAGE_KEY, DEFAULT_TOKEN_STORAGE_KEY, ForbiddenError, HttpClient, LocalStorageAdapter, MemoryStorage, NetworkError, NotFoundError, PhoneService, RateLimitError, ServerError, SessionService, TimeoutError, UnprocessableError, ValidationError, createAuthInterceptor, createDeviceSignalInterceptor, createErrorFromResponse, decodeJwtPayload, hasDevice, validatePhoneNumber, validateUsername };
1319
+ export { AuthClient, AuthError, AuthErrorCode, AuthService, AuthenticationError, BackgroundRefresh, BrowserDeviceSignalCollector, ConflictError, CookieStorage, DEFAULT_LAST_LOGIN_METHOD_KEY, DEFAULT_REFRESH_TOKEN_STORAGE_KEY, DEFAULT_SESSION_STORAGE_KEY, DEFAULT_TOKEN_STORAGE_KEY, DeviceService, ForbiddenError, HttpClient, LocalStorageAdapter, LoginActivityService, MemoryStorage, NetworkError, NotFoundError, OrganizationService, PhoneService, RISK_LEVEL_HIGH, RISK_LEVEL_LOW, RISK_LEVEL_MEDIUM, RISK_LEVEL_NONE, RateLimitError, ServerError, SessionService, TimeoutError, UnprocessableError, ValidationError, createAuthInterceptor, createDeviceSignalInterceptor, createErrorFromResponse, decodeJwtPayload, getRiskLevel, hasDevice, validatePhoneNumber, validateUsername };
1146
1320
  //# sourceMappingURL=index.js.map
1147
1321
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/device/browser-collector.ts","../src/errors/auth-error.ts","../src/errors/errors.ts","../src/errors/factory.ts","../src/http/rate-limit.ts","../src/http/retry.ts","../src/http/client.ts","../src/http/interceptors/auth.ts","../src/http/interceptors/device-signals.ts","../src/types/config.ts","../src/services/validators.ts","../src/services/auth.ts","../src/services/refresh.ts","../src/services/phone.ts","../src/services/session.ts","../src/storage/cookie-storage.ts","../src/storage/local-storage-adapter.ts","../src/storage/memory-storage.ts","../src/client.ts","../src/types/session.ts","../src/errors/codes.ts"],"names":["AuthErrorCode"],"mappings":"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","file":"index.js","sourcesContent":["// Browser Device Signal Collector — SSR-safe\n\nimport type { DeviceSignals, IDeviceSignalCollector } from \"./types\";\n\nconst EMPTY_SIGNALS: DeviceSignals = {\n screen: \"\",\n timezone: \"\",\n platform: \"\",\n language: \"\",\n colorDepth: \"\",\n touchSupport: \"\",\n};\n\nfunction simpleHash(input: string): string {\n let hash = 0;\n for (let i = 0; i < input.length; i++) {\n const char = input.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash |= 0;\n }\n return Math.abs(hash).toString(16).padStart(8, \"0\");\n}\n\nasync function sha256Hash(input: string): Promise<string> {\n try {\n if (typeof globalThis.crypto?.subtle?.digest === \"function\") {\n const encoder = new TextEncoder();\n const data = encoder.encode(input);\n const hashBuffer = await globalThis.crypto.subtle.digest(\"SHA-256\", data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n }\n } catch {\n // Fallback below\n }\n return simpleHash(input);\n}\n\nexport class BrowserDeviceSignalCollector implements IDeviceSignalCollector {\n private cached: DeviceSignals | null = null;\n private cachedFingerprint: string | null = null;\n\n async collect(): Promise<DeviceSignals> {\n if (this.cached) return this.cached;\n\n if (typeof window === \"undefined\" || typeof navigator === \"undefined\") {\n this.cached = EMPTY_SIGNALS;\n return this.cached;\n }\n\n this.cached = {\n screen: `${screen.width}x${screen.height}`,\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n platform: navigator.platform,\n language: navigator.language,\n colorDepth: String(screen.colorDepth),\n touchSupport: String(\"ontouchstart\" in window),\n };\n\n return this.cached;\n }\n\n async getFingerprint(): Promise<string> {\n if (this.cachedFingerprint) return this.cachedFingerprint;\n\n const signals = await this.collect();\n const raw = [\n signals.screen,\n signals.timezone,\n signals.platform,\n signals.language,\n signals.colorDepth,\n signals.touchSupport,\n ].join(\"|\");\n\n this.cachedFingerprint = await sha256Hash(raw);\n return this.cachedFingerprint;\n }\n}\n","// Base Auth Error\n\nimport type { AuthErrorCode } from \"./codes\";\n\nexport interface AuthErrorOptions {\n code: AuthErrorCode;\n message: string;\n statusCode: number;\n details?: Record<string, unknown>;\n requestId?: string;\n}\n\nexport class AuthError extends Error {\n readonly code: AuthErrorCode;\n readonly statusCode: number;\n readonly details?: Record<string, unknown>;\n readonly requestId?: string;\n\n constructor(options: AuthErrorOptions) {\n super(options.message);\n this.name = \"AuthError\";\n this.code = options.code;\n this.statusCode = options.statusCode;\n this.details = options.details;\n this.requestId = options.requestId;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n toJSON(): Record<string, unknown> {\n return {\n code: this.code,\n message: this.message,\n statusCode: this.statusCode,\n details: this.details,\n requestId: this.requestId,\n };\n }\n}\n","// Error Subclasses\n\nimport { AuthError, type AuthErrorOptions } from \"./auth-error\";\nimport type { AuthErrorCode } from \"./codes\";\n\ntype SubclassOptions = Omit<AuthErrorOptions, \"statusCode\"> & { statusCode?: number };\n\nexport class ValidationError extends AuthError {\n constructor(options: SubclassOptions) {\n super({ ...options, statusCode: options.statusCode ?? 400 });\n this.name = \"ValidationError\";\n }\n}\n\nexport class AuthenticationError extends AuthError {\n constructor(options: SubclassOptions) {\n super({ ...options, statusCode: options.statusCode ?? 401 });\n this.name = \"AuthenticationError\";\n }\n}\n\nexport class ForbiddenError extends AuthError {\n constructor(options: SubclassOptions) {\n super({ ...options, statusCode: options.statusCode ?? 403 });\n this.name = \"ForbiddenError\";\n }\n}\n\nexport class NotFoundError extends AuthError {\n constructor(options: SubclassOptions) {\n super({ ...options, statusCode: options.statusCode ?? 404 });\n this.name = \"NotFoundError\";\n }\n}\n\nexport class ConflictError extends AuthError {\n constructor(options: SubclassOptions) {\n super({ ...options, statusCode: options.statusCode ?? 409 });\n this.name = \"ConflictError\";\n }\n}\n\nexport class UnprocessableError extends AuthError {\n constructor(options: SubclassOptions) {\n super({ ...options, statusCode: options.statusCode ?? 422 });\n this.name = \"UnprocessableError\";\n }\n}\n\nexport interface RateLimitErrorOptions extends SubclassOptions {\n retryAfter: number;\n}\n\nexport class RateLimitError extends AuthError {\n readonly retryAfter: number;\n\n constructor(options: RateLimitErrorOptions) {\n super({ ...options, statusCode: options.statusCode ?? 429 });\n this.name = \"RateLimitError\";\n this.retryAfter = options.retryAfter;\n }\n\n override toJSON(): Record<string, unknown> {\n return { ...super.toJSON(), retryAfter: this.retryAfter };\n }\n}\n\nexport class ServerError extends AuthError {\n constructor(options: SubclassOptions) {\n super({ ...options, statusCode: options.statusCode ?? 500 });\n this.name = \"ServerError\";\n }\n}\n\nexport interface NetworkErrorOptions {\n message: string;\n code?: AuthErrorCode;\n details?: Record<string, unknown>;\n requestId?: string;\n}\n\nexport class NetworkError extends AuthError {\n constructor(options: NetworkErrorOptions) {\n super({\n code: options.code ?? (\"NETWORK_ERROR\" as AuthErrorCode),\n message: options.message,\n statusCode: 0,\n details: options.details,\n requestId: options.requestId,\n });\n this.name = \"NetworkError\";\n }\n}\n\nexport interface TimeoutErrorOptions {\n duration: number;\n message?: string;\n requestId?: string;\n}\n\nexport class TimeoutError extends AuthError {\n readonly duration: number;\n\n constructor(options: TimeoutErrorOptions) {\n super({\n code: \"TIMEOUT\" as AuthErrorCode,\n message: options.message ?? `Request timed out after ${options.duration}ms`,\n statusCode: 0,\n requestId: options.requestId,\n });\n this.name = \"TimeoutError\";\n this.duration = options.duration;\n }\n\n override toJSON(): Record<string, unknown> {\n return { ...super.toJSON(), duration: this.duration };\n }\n}\n","// Error Factory — maps HTTP responses to typed errors\n\nimport { AuthError } from \"./auth-error\";\nimport type { AuthErrorCode } from \"./codes\";\nimport {\n AuthenticationError,\n ConflictError,\n ForbiddenError,\n NotFoundError,\n RateLimitError,\n ServerError,\n UnprocessableError,\n ValidationError,\n} from \"./errors\";\n\ninterface ErrorBody {\n code?: string;\n message?: string;\n details?: Record<string, unknown>;\n}\n\nfunction parseBody(body: unknown): ErrorBody {\n if (body && typeof body === \"object\" && \"message\" in body) {\n const obj = body as Record<string, unknown>;\n return {\n code: typeof obj.code === \"string\" ? obj.code : undefined,\n message: typeof obj.message === \"string\" ? obj.message : \"Unknown error\",\n details:\n typeof obj.details === \"object\" && obj.details !== null\n ? (obj.details as Record<string, unknown>)\n : undefined,\n };\n }\n return { message: \"Unknown error\" };\n}\n\nexport function parseRetryAfterHeader(header: string | null): number {\n if (!header) return 60;\n\n const seconds = Number(header);\n if (!Number.isNaN(seconds)) return seconds;\n\n const date = new Date(header);\n if (!Number.isNaN(date.getTime())) {\n return Math.max(0, Math.ceil((date.getTime() - Date.now()) / 1000));\n }\n\n return 60;\n}\n\nexport function createErrorFromResponse(\n status: number,\n body: unknown,\n headers: Headers,\n): AuthError {\n const parsed = parseBody(body);\n const requestId = headers.get(\"x-request-id\") ?? undefined;\n const code = (parsed.code ?? \"NETWORK_ERROR\") as AuthErrorCode;\n const message = parsed.message ?? `HTTP ${status}`;\n const details = parsed.details;\n const base = { code, message, details, requestId };\n\n switch (true) {\n case status === 400:\n return new ValidationError(base);\n case status === 401:\n return new AuthenticationError(base);\n case status === 403:\n return new ForbiddenError(base);\n case status === 404:\n return new NotFoundError(base);\n case status === 409:\n return new ConflictError(base);\n case status === 422:\n return new UnprocessableError(base);\n case status === 429: {\n const retryAfter = parseRetryAfterHeader(headers.get(\"retry-after\"));\n return new RateLimitError({ ...base, retryAfter });\n }\n case status >= 500 && status < 600:\n return new ServerError(base);\n default:\n return new AuthError({ ...base, statusCode: status });\n }\n}\n","// Rate Limit Handling\n\nimport type { RateLimitConfig } from \"./types\";\n\nexport const DEFAULT_RATE_LIMIT_CONFIG: RateLimitConfig = {\n autoRetry: true,\n maxRetryAfter: 60,\n};\n\nexport function mergeRateLimitConfig(config?: Partial<RateLimitConfig>): RateLimitConfig {\n return { ...DEFAULT_RATE_LIMIT_CONFIG, ...config };\n}\n\nexport function parseRetryAfter(header: string | null): number {\n if (!header) return 60;\n\n const seconds = Number(header);\n if (!Number.isNaN(seconds)) return seconds;\n\n const date = new Date(header);\n if (!Number.isNaN(date.getTime())) {\n return Math.max(0, Math.ceil((date.getTime() - Date.now()) / 1000));\n }\n\n return 60;\n}\n","// Retry Logic with Exponential Backoff\n\nimport type { RetryConfig } from \"./types\";\n\nexport const DEFAULT_RETRY_CONFIG: RetryConfig = {\n maxRetries: 3,\n baseDelay: 1000,\n maxDelay: 10000,\n factor: 2,\n jitter: true,\n retryableStatuses: [500, 502, 503, 504],\n retryPost: false,\n};\n\nexport function mergeRetryConfig(config?: Partial<RetryConfig>): RetryConfig {\n return { ...DEFAULT_RETRY_CONFIG, ...config };\n}\n\nexport function shouldRetry(\n error: unknown,\n attempt: number,\n method: string,\n config: RetryConfig,\n): boolean {\n if (attempt >= config.maxRetries) return false;\n if (method === \"POST\" && !config.retryPost) return false;\n\n // Network error (TypeError from fetch)\n if (error instanceof TypeError) return true;\n\n // Check statusCode on error objects\n if (error && typeof error === \"object\" && \"statusCode\" in error) {\n const statusCode = (error as { statusCode: number }).statusCode;\n return config.retryableStatuses.includes(statusCode);\n }\n\n return false;\n}\n\nexport function calculateDelay(attempt: number, config: RetryConfig): number {\n const exponential = config.baseDelay * config.factor ** attempt;\n const delay = Math.min(exponential, config.maxDelay);\n\n if (!config.jitter) return delay;\n\n return Math.round(delay * Math.random());\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","// HTTP Client — zero-dependency fetch wrapper\n\nimport { NetworkError, RateLimitError, TimeoutError } from \"../errors/errors\";\nimport { createErrorFromResponse } from \"../errors/factory\";\nimport { mergeRateLimitConfig } from \"./rate-limit\";\nimport { calculateDelay, mergeRetryConfig, shouldRetry, sleep } from \"./retry\";\nimport type {\n ApiResponse,\n ErrorInterceptor,\n HttpClientConfig,\n RateLimitConfig,\n RequestConfig,\n RequestInterceptor,\n ResponseInterceptor,\n RetryConfig,\n} from \"./types\";\n\nexport class HttpClient {\n private readonly config: HttpClientConfig;\n private readonly retryConfig: RetryConfig;\n private readonly rateLimitConfig: RateLimitConfig;\n private requestInterceptors: RequestInterceptor[] = [];\n private responseInterceptors: ResponseInterceptor[] = [];\n private errorInterceptors: ErrorInterceptor[] = [];\n\n constructor(config: HttpClientConfig) {\n this.config = config;\n this.retryConfig = mergeRetryConfig(config.retry);\n this.rateLimitConfig = mergeRateLimitConfig(config.rateLimit);\n }\n\n // --- Public HTTP Methods ---\n\n async get<T>(\n path: string,\n config?: Partial<Omit<RequestConfig, \"method\" | \"path\" | \"body\">>,\n ): Promise<ApiResponse<T>> {\n return this.request<T>({ ...config, method: \"GET\", path });\n }\n\n async post<T>(\n path: string,\n body?: unknown,\n config?: Partial<Omit<RequestConfig, \"method\" | \"path\" | \"body\">>,\n ): Promise<ApiResponse<T>> {\n return this.request<T>({ ...config, method: \"POST\", path, body });\n }\n\n async put<T>(\n path: string,\n body?: unknown,\n config?: Partial<Omit<RequestConfig, \"method\" | \"path\" | \"body\">>,\n ): Promise<ApiResponse<T>> {\n return this.request<T>({ ...config, method: \"PUT\", path, body });\n }\n\n async patch<T>(\n path: string,\n body?: unknown,\n config?: Partial<Omit<RequestConfig, \"method\" | \"path\" | \"body\">>,\n ): Promise<ApiResponse<T>> {\n return this.request<T>({ ...config, method: \"PATCH\", path, body });\n }\n\n async delete<T>(\n path: string,\n config?: Partial<Omit<RequestConfig, \"method\" | \"path\" | \"body\">>,\n ): Promise<ApiResponse<T>> {\n return this.request<T>({ ...config, method: \"DELETE\", path });\n }\n\n getBaseUrl(): string {\n return this.config.baseUrl;\n }\n\n // --- Interceptor Management ---\n\n addRequestInterceptor(fn: RequestInterceptor): void {\n this.requestInterceptors.push(fn);\n }\n\n removeRequestInterceptor(fn: RequestInterceptor): void {\n this.requestInterceptors = this.requestInterceptors.filter((i) => i !== fn);\n }\n\n addResponseInterceptor(fn: ResponseInterceptor): void {\n this.responseInterceptors.push(fn);\n }\n\n removeResponseInterceptor(fn: ResponseInterceptor): void {\n this.responseInterceptors = this.responseInterceptors.filter((i) => i !== fn);\n }\n\n addErrorInterceptor(fn: ErrorInterceptor): void {\n this.errorInterceptors.push(fn);\n }\n\n removeErrorInterceptor(fn: ErrorInterceptor): void {\n this.errorInterceptors = this.errorInterceptors.filter((i) => i !== fn);\n }\n\n // --- Internal ---\n\n private async request<T>(initialConfig: RequestConfig): Promise<ApiResponse<T>> {\n // Run request interceptors\n let config = { ...initialConfig };\n for (const interceptor of this.requestInterceptors) {\n config = await interceptor(config);\n }\n\n // Build URL\n const url = new URL(config.path, this.config.baseUrl);\n if (config.params) {\n for (const [key, value] of Object.entries(config.params)) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n // Build headers\n const headers: Record<string, string> = {\n ...this.config.headers,\n ...config.headers,\n };\n if (config.body !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n // Retry loop\n const maxAttempts = this.retryConfig.maxRetries + 1;\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n return await this.executeFetch<T>(url, headers, config, attempt);\n } catch (error) {\n // Run error interceptors\n let processedError = error;\n for (const interceptor of this.errorInterceptors) {\n processedError = await interceptor(processedError);\n }\n\n // Rate limit: handle 429 separately from general retry\n if (processedError instanceof RateLimitError) {\n if (\n this.rateLimitConfig.autoRetry &&\n processedError.retryAfter <= this.rateLimitConfig.maxRetryAfter &&\n attempt === 0\n ) {\n await sleep(processedError.retryAfter * 1000);\n continue;\n }\n throw processedError;\n }\n\n // General retry\n if (shouldRetry(processedError, attempt, config.method, this.retryConfig)) {\n const delay = calculateDelay(attempt, this.retryConfig);\n await sleep(delay);\n continue;\n }\n\n throw processedError;\n }\n }\n\n // Should not reach here, but satisfy TypeScript\n throw new NetworkError({ message: \"Max retries exceeded\" });\n }\n\n private async executeFetch<T>(\n url: URL,\n headers: Record<string, string>,\n config: RequestConfig,\n _attempt: number,\n ): Promise<ApiResponse<T>> {\n const timeout = config.timeout ?? this.config.timeout ?? 30_000;\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(url.toString(), {\n method: config.method,\n headers,\n body: config.body !== undefined ? JSON.stringify(config.body) : undefined,\n signal: config.signal ?? controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n // Handle error responses\n if (!response.ok) {\n let body: unknown;\n try {\n body = await response.json();\n } catch {\n body = { message: response.statusText };\n }\n throw createErrorFromResponse(response.status, body, response.headers);\n }\n\n // Parse successful response\n let data: T;\n if (response.status === 204) {\n data = undefined as T;\n } else {\n data = (await response.json()) as T;\n }\n\n let result: ApiResponse<unknown> = {\n data,\n status: response.status,\n headers: response.headers,\n };\n\n // Run response interceptors\n for (const interceptor of this.responseInterceptors) {\n result = await interceptor(result);\n }\n\n return result as ApiResponse<T>;\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof DOMException && error.name === \"AbortError\") {\n throw new TimeoutError({ duration: timeout });\n }\n\n if (error instanceof TypeError) {\n throw new NetworkError({ message: error.message });\n }\n\n throw error;\n }\n }\n}\n","// Auth Header Interceptor\n\nimport type { RequestInterceptor } from \"../types\";\n\nexport interface AuthInterceptorConfig {\n tokenProvider?: () => string | null;\n apiKey?: string;\n}\n\nexport function createAuthInterceptor(config: AuthInterceptorConfig): RequestInterceptor {\n return (request) => {\n if (request.skipAuth) return request;\n\n const headers = { ...request.headers };\n\n if (config.tokenProvider) {\n const token = config.tokenProvider();\n if (token) {\n headers.Authorization = `Bearer ${token}`;\n }\n }\n\n if (config.apiKey) {\n headers[\"x-api-key\"] = config.apiKey;\n }\n\n return { ...request, headers };\n };\n}\n","// Device Signal Header Interceptor\n\nimport type { IDeviceSignalCollector } from \"../../device/types\";\nimport type { RequestInterceptor } from \"../types\";\n\nexport function createDeviceSignalInterceptor(\n collector: IDeviceSignalCollector,\n): RequestInterceptor {\n return async (request) => {\n const signals = await collector.collect();\n\n // Skip if no signals collected (SSR)\n if (!signals.screen && !signals.timezone && !signals.platform) {\n return request;\n }\n\n const fingerprint = await collector.getFingerprint();\n\n const headers: Record<string, string> = {\n ...request.headers,\n \"x-device-screen\": signals.screen,\n \"x-device-timezone\": signals.timezone,\n \"x-device-platform\": signals.platform,\n \"x-device-language\": signals.language,\n \"x-device-color-depth\": signals.colorDepth,\n \"x-device-touch\": signals.touchSupport,\n \"x-device-fingerprint\": fingerprint,\n };\n\n return { ...request, headers };\n };\n}\n","// Auth Client Configuration v2.0\n\nimport type { ITokenStorage } from \"../storage/types\";\nimport type { LoginAlert } from \"./auth\";\n\nexport interface AuthConfig {\n // API Configuration\n apiKey?: string;\n baseUrl: string;\n timeout?: number;\n\n // Storage Configuration\n tokenStorageKey?: string;\n sessionStorageKey?: string;\n\n // Token Management\n autoRefreshToken?: boolean;\n refreshThreshold?: number;\n\n // v2.0: Device Signal Collection\n collectDeviceSignals?: boolean;\n\n // Callbacks\n onSessionExpired?: () => void;\n onTokenRefreshed?: (token: string) => void;\n onNewDeviceAlert?: (alert: LoginAlert) => void;\n\n // Platform-specific\n storage?: ITokenStorage;\n}\n\n// Storage key defaults\nexport const DEFAULT_TOKEN_STORAGE_KEY = \"atz_auth_token\";\nexport const DEFAULT_REFRESH_TOKEN_STORAGE_KEY = \"atz_refresh_token\";\nexport const DEFAULT_SESSION_STORAGE_KEY = \"atz_session\";\nexport const DEFAULT_LAST_LOGIN_METHOD_KEY = \"atz_last_login_method\";\n","// Client-side validation helpers\n\nimport { ValidationError } from \"../errors/errors\";\n\nconst USERNAME_MIN_LENGTH = 3;\nconst USERNAME_MAX_LENGTH = 20;\nconst USERNAME_PATTERN = /^[a-z0-9]+$/;\n\nconst PHONE_E164_PATTERN = /^\\+\\d{10,15}$/;\nconst SUPPORTED_COUNTRY_CODES = [\"+30\", \"+49\"];\n\nexport function validateUsername(username: string): void {\n if (username.length < USERNAME_MIN_LENGTH) {\n throw new ValidationError({\n code: \"USERNAME_INVALID\" as never,\n message: `Username must be at least ${USERNAME_MIN_LENGTH} characters`,\n });\n }\n if (username.length > USERNAME_MAX_LENGTH) {\n throw new ValidationError({\n code: \"USERNAME_INVALID\" as never,\n message: `Username must be at most ${USERNAME_MAX_LENGTH} characters`,\n });\n }\n if (!USERNAME_PATTERN.test(username)) {\n throw new ValidationError({\n code: \"USERNAME_INVALID\" as never,\n message: \"Username must contain only lowercase letters and numbers\",\n });\n }\n}\n\nexport function validatePhoneNumber(phoneNumber: string): void {\n if (!PHONE_E164_PATTERN.test(phoneNumber)) {\n throw new ValidationError({\n code: \"INVALID_PHONE_NUMBER\" as never,\n message: \"Phone number must be in E.164 format (e.g. +301234567890)\",\n });\n }\n const hasValidCountryCode = SUPPORTED_COUNTRY_CODES.some((code) => phoneNumber.startsWith(code));\n if (!hasValidCountryCode) {\n throw new ValidationError({\n code: \"INVALID_PHONE_NUMBER\" as never,\n message: `Phone number must start with one of: ${SUPPORTED_COUNTRY_CODES.join(\", \")}`,\n });\n }\n}\n","// Authentication Service\n\nimport type { HttpClient } from \"../http/client\";\nimport type { ITokenStorage } from \"../storage/types\";\nimport type {\n LoginCredentials,\n LoginResponse,\n RefreshTokenResponse,\n RequestPasswordResetRequest,\n ResetPasswordRequest,\n ResetPasswordResponse,\n SendMagicLinkRequest,\n SendVerificationEmailRequest,\n SignupData,\n SignupResponse,\n UsernameLoginCredentials,\n VerifyEmailRequest,\n VerifyEmailResponse,\n VerifyMagicLinkRequest,\n} from \"../types/auth\";\nimport {\n DEFAULT_LAST_LOGIN_METHOD_KEY,\n DEFAULT_REFRESH_TOKEN_STORAGE_KEY,\n DEFAULT_SESSION_STORAGE_KEY,\n DEFAULT_TOKEN_STORAGE_KEY,\n} from \"../types/config\";\nimport { validateUsername } from \"./validators\";\n\nexport class AuthService {\n private readonly httpClient: HttpClient;\n private readonly storage: ITokenStorage;\n private readonly tokenStorageKey: string;\n private readonly refreshTokenStorageKey: string;\n private readonly sessionStorageKey: string;\n private readonly lastLoginMethodKey: string;\n private refreshPromise: Promise<RefreshTokenResponse> | null = null;\n\n constructor(\n httpClient: HttpClient,\n storage: ITokenStorage,\n options?: {\n tokenStorageKey?: string;\n refreshTokenStorageKey?: string;\n sessionStorageKey?: string;\n lastLoginMethodKey?: string;\n },\n ) {\n this.httpClient = httpClient;\n this.storage = storage;\n this.tokenStorageKey = options?.tokenStorageKey ?? DEFAULT_TOKEN_STORAGE_KEY;\n this.refreshTokenStorageKey =\n options?.refreshTokenStorageKey ?? DEFAULT_REFRESH_TOKEN_STORAGE_KEY;\n this.sessionStorageKey = options?.sessionStorageKey ?? DEFAULT_SESSION_STORAGE_KEY;\n this.lastLoginMethodKey = options?.lastLoginMethodKey ?? DEFAULT_LAST_LOGIN_METHOD_KEY;\n }\n\n // --- Email/Password Login & Signup (T02-001) ---\n\n async login(credentials: LoginCredentials): Promise<LoginResponse> {\n const { data } = await this.httpClient.post<LoginResponse>(\"/auth/login\", credentials, {\n skipAuth: true,\n });\n\n await this.storeTokens(data.accessToken, data.refreshToken);\n await this.setLastLoginMethod(\"email\");\n\n return data;\n }\n\n async signup(data: SignupData): Promise<SignupResponse> {\n const { data: response } = await this.httpClient.post<SignupResponse>(\"/auth/signup\", data, {\n skipAuth: true,\n });\n\n await this.storeTokens(response.accessToken, response.refreshToken);\n await this.setLastLoginMethod(\"email\");\n\n return response;\n }\n\n // --- Username Login (T02-002) ---\n\n async loginWithUsername(credentials: UsernameLoginCredentials): Promise<LoginResponse> {\n validateUsername(credentials.username);\n\n const { data } = await this.httpClient.post<LoginResponse>(\n \"/auth/login/username\",\n credentials,\n { skipAuth: true },\n );\n\n await this.storeTokens(data.accessToken, data.refreshToken);\n await this.setLastLoginMethod(\"username\");\n\n return data;\n }\n\n async isUsernameAvailable(username: string): Promise<boolean> {\n validateUsername(username);\n\n const { data } = await this.httpClient.get<{ available: boolean }>(\"/auth/username/available\", {\n params: { username },\n });\n\n return data.available;\n }\n\n // --- OAuth (T02-004) ---\n\n getOAuthUrl(request: {\n provider: string;\n redirectUri: string;\n state: string;\n scopes?: string[];\n }): string {\n const baseUrl = this.httpClient.getBaseUrl();\n const params = new URLSearchParams({\n provider: request.provider,\n redirect_uri: request.redirectUri,\n state: request.state,\n });\n if (request.scopes?.length) {\n params.set(\"scopes\", request.scopes.join(\",\"));\n }\n return `${baseUrl}/auth/oauth/authorize?${params.toString()}`;\n }\n\n async verifyOAuthCode(request: {\n provider: string;\n code: string;\n redirectUri: string;\n }): Promise<LoginResponse> {\n const { data } = await this.httpClient.post<LoginResponse>(\"/auth/oauth/verify\", request, {\n skipAuth: true,\n });\n\n await this.storeTokens(data.accessToken, data.refreshToken);\n await this.setLastLoginMethod(\"oauth\");\n\n return data;\n }\n\n // --- Magic Link (T02-005) ---\n\n async sendMagicLink(request: SendMagicLinkRequest): Promise<void> {\n await this.httpClient.post(\"/auth/magic-link/send\", request, { skipAuth: true });\n }\n\n async verifyMagicLink(request: VerifyMagicLinkRequest): Promise<LoginResponse> {\n const { data } = await this.httpClient.post<LoginResponse>(\"/auth/magic-link/verify\", request, {\n skipAuth: true,\n });\n\n await this.storeTokens(data.accessToken, data.refreshToken);\n await this.setLastLoginMethod(\"magic_link\");\n\n return data;\n }\n\n // --- Email Verification (T02-006) ---\n\n async sendVerificationEmail(request: SendVerificationEmailRequest): Promise<void> {\n await this.httpClient.post(\"/auth/email/send-verification\", request);\n }\n\n async verifyEmail(request: VerifyEmailRequest): Promise<VerifyEmailResponse> {\n const { data } = await this.httpClient.post<VerifyEmailResponse>(\n \"/auth/email/verify\",\n request,\n { skipAuth: true },\n );\n return data;\n }\n\n // --- Password Reset (T02-007) ---\n\n async requestPasswordReset(request: RequestPasswordResetRequest): Promise<void> {\n await this.httpClient.post(\"/auth/password/reset-request\", request, { skipAuth: true });\n }\n\n async resetPassword(request: ResetPasswordRequest): Promise<ResetPasswordResponse> {\n const { data } = await this.httpClient.post<ResetPasswordResponse>(\n \"/auth/password/reset\",\n request,\n { skipAuth: true },\n );\n return data;\n }\n\n // --- Token Management (T02-009) ---\n\n async getAccessToken(): Promise<string | null> {\n return this.storage.get(this.tokenStorageKey);\n }\n\n async refreshToken(): Promise<RefreshTokenResponse> {\n if (this.refreshPromise) {\n return this.refreshPromise;\n }\n\n this.refreshPromise = this.executeRefresh();\n try {\n return await this.refreshPromise;\n } finally {\n this.refreshPromise = null;\n }\n }\n\n async isAuthenticated(): Promise<boolean> {\n const token = await this.storage.get(this.tokenStorageKey);\n if (!token) return false;\n\n const decoded = decodeJwtPayload(token);\n if (!decoded) return false;\n\n return decoded.exp * 1000 > Date.now();\n }\n\n async getLastLoginMethod(): Promise<string | null> {\n return this.storage.get(this.lastLoginMethodKey);\n }\n\n // --- Logout (T02-010) ---\n\n async logout(): Promise<void> {\n try {\n await this.httpClient.post(\"/auth/logout\", {});\n } catch {\n // Fire-and-forget: always clear tokens even if API call fails\n }\n await this.clearTokens();\n }\n\n async logoutAllDevices(): Promise<void> {\n try {\n await this.httpClient.post(\"/auth/logout/all\", {});\n } catch {\n // Fire-and-forget: always clear tokens even if API call fails\n }\n await this.clearTokens();\n }\n\n // --- Storage Helpers ---\n\n async storeTokens(accessToken: string, refreshToken: string): Promise<void> {\n await this.storage.set(this.tokenStorageKey, accessToken);\n await this.storage.set(this.refreshTokenStorageKey, refreshToken);\n }\n\n async setLastLoginMethod(method: string): Promise<void> {\n await this.storage.set(this.lastLoginMethodKey, method);\n }\n\n async clearTokens(): Promise<void> {\n await this.storage.remove(this.tokenStorageKey);\n await this.storage.remove(this.refreshTokenStorageKey);\n await this.storage.remove(this.sessionStorageKey);\n await this.storage.remove(this.lastLoginMethodKey);\n }\n\n // --- Private ---\n\n private async executeRefresh(): Promise<RefreshTokenResponse> {\n const currentRefreshToken = await this.storage.get(this.refreshTokenStorageKey);\n const { data } = await this.httpClient.post<RefreshTokenResponse>(\"/auth/token/refresh\", {\n refreshToken: currentRefreshToken,\n });\n await this.storeTokens(data.accessToken, data.refreshToken);\n return data;\n }\n}\n\n// --- JWT Decode Utility ---\n\nexport function decodeJwtPayload(token: string): {\n sub: string;\n email: string;\n name: string;\n exp: number;\n iat: number;\n org?: string;\n roles?: string[];\n} | null {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n\n const payload = parts[1];\n // Base64url to base64\n const base64 = payload.replace(/-/g, \"+\").replace(/_/g, \"/\");\n // Pad if needed\n const padded = base64 + \"=\".repeat((4 - (base64.length % 4)) % 4);\n const decoded = atob(padded);\n return JSON.parse(decoded);\n } catch {\n return null;\n }\n}\n","// Background Token Refresh — automatic token refresh before expiration\n\nexport class BackgroundRefresh {\n private timerId: ReturnType<typeof setTimeout> | null = null;\n private retryTimerId: ReturnType<typeof setTimeout> | null = null;\n\n constructor(\n private readonly refreshFn: () => Promise<{\n accessToken: string;\n expiresIn: number;\n }>,\n private readonly threshold: number,\n private readonly callbacks: {\n onTokenRefreshed?: (token: string) => void;\n onSessionExpired?: () => void;\n } = {},\n ) {}\n\n start(expiresIn: number): void {\n if (typeof setTimeout === \"undefined\") return;\n\n this.stop();\n\n const delayMs = (expiresIn - this.threshold) * 1000;\n\n if (delayMs <= 0) {\n this.executeRefresh();\n return;\n }\n\n this.timerId = setTimeout(() => {\n this.executeRefresh();\n }, delayMs);\n }\n\n stop(): void {\n if (this.timerId !== null) {\n clearTimeout(this.timerId);\n this.timerId = null;\n }\n if (this.retryTimerId !== null) {\n clearTimeout(this.retryTimerId);\n this.retryTimerId = null;\n }\n }\n\n isRunning(): boolean {\n return this.timerId !== null;\n }\n\n private async executeRefresh(): Promise<void> {\n try {\n const result = await this.refreshFn();\n this.callbacks.onTokenRefreshed?.(result.accessToken);\n this.start(result.expiresIn);\n } catch {\n this.timerId = null;\n this.retryTimerId = setTimeout(async () => {\n this.retryTimerId = null;\n try {\n const result = await this.refreshFn();\n this.callbacks.onTokenRefreshed?.(result.accessToken);\n this.start(result.expiresIn);\n } catch {\n this.callbacks.onSessionExpired?.();\n }\n }, 5000);\n }\n }\n}\n","// Phone Authentication Service (v2.0)\n\nimport type { HttpClient } from \"../http/client\";\nimport type { LoginResponse } from \"../types/auth\";\nimport type {\n PhoneSignInRequest,\n SendOTPRequest,\n SendOTPResponse,\n VerifyOTPRequest,\n VerifyOTPResponse,\n} from \"../types/phone\";\nimport { validatePhoneNumber } from \"./validators\";\n\nexport class PhoneService {\n private readonly httpClient: HttpClient;\n private readonly storeTokensFn: (accessToken: string, refreshToken: string) => Promise<void>;\n private readonly setLastLoginMethodFn: (method: string) => Promise<void>;\n\n constructor(\n httpClient: HttpClient,\n storeTokens: (accessToken: string, refreshToken: string) => Promise<void>,\n setLastLoginMethod: (method: string) => Promise<void>,\n ) {\n this.httpClient = httpClient;\n this.storeTokensFn = storeTokens;\n this.setLastLoginMethodFn = setLastLoginMethod;\n }\n\n async sendOTP(request: SendOTPRequest): Promise<SendOTPResponse> {\n validatePhoneNumber(request.phoneNumber);\n\n const { data } = await this.httpClient.post<SendOTPResponse>(\"/auth/phone/send-otp\", request, {\n skipAuth: true,\n });\n return data;\n }\n\n async verify(request: VerifyOTPRequest): Promise<VerifyOTPResponse> {\n validatePhoneNumber(request.phoneNumber);\n\n const { data } = await this.httpClient.post<VerifyOTPResponse>(\"/auth/phone/verify\", request, {\n skipAuth: true,\n });\n\n await this.storeTokensFn(data.accessToken, data.refreshToken);\n await this.setLastLoginMethodFn(\"phone\");\n\n return data;\n }\n\n async signIn(request: PhoneSignInRequest): Promise<LoginResponse> {\n validatePhoneNumber(request.phoneNumber);\n\n const { data } = await this.httpClient.post<LoginResponse>(\"/auth/phone/sign-in\", request, {\n skipAuth: true,\n });\n\n await this.storeTokensFn(data.accessToken, data.refreshToken);\n await this.setLastLoginMethodFn(\"phone\");\n\n return data;\n }\n}\n","// Session Service — session CRUD, multi-session, device summary\n\nimport type { HttpClient } from \"../http/client\";\nimport type {\n DeviceSession,\n DeviceSummary,\n ListSessionsRequest,\n ListSessionsResponse,\n RevokeAllSessionsOptions,\n RevokeAllSessionsResponse,\n Session,\n SetActiveSessionRequest,\n SetActiveSessionResponse,\n} from \"../types/session\";\n\nexport class SessionService {\n private readonly httpClient: HttpClient;\n private readonly storeTokens: (accessToken: string, refreshToken: string) => Promise<void>;\n\n constructor(\n httpClient: HttpClient,\n storeTokens: (accessToken: string, refreshToken: string) => Promise<void>,\n ) {\n this.httpClient = httpClient;\n this.storeTokens = storeTokens;\n }\n\n // --- Session CRUD (T03-001) ---\n\n async getCurrent(): Promise<Session> {\n const { data } = await this.httpClient.get<Session>(\"/auth/sessions/current\");\n return data;\n }\n\n async list(options?: ListSessionsRequest): Promise<ListSessionsResponse> {\n const params: Record<string, string | number> = {};\n if (options?.limit !== undefined) params.limit = options.limit;\n if (options?.offset !== undefined) params.offset = options.offset;\n\n const { data } = await this.httpClient.get<ListSessionsResponse>(\"/auth/sessions\", { params });\n return data;\n }\n\n async revoke(sessionId: string): Promise<void> {\n await this.httpClient.delete(`/auth/sessions/${sessionId}`);\n }\n\n // --- Revoke All (T03-002) ---\n\n async revokeAll(options?: RevokeAllSessionsOptions): Promise<RevokeAllSessionsResponse> {\n const { data } = await this.httpClient.post<RevokeAllSessionsResponse>(\n \"/auth/sessions/revoke-all\",\n { exceptCurrent: options?.exceptCurrent ?? true },\n );\n return data;\n }\n\n // --- Multi-Session (T03-003, T03-004) ---\n\n async listDeviceSessions(): Promise<DeviceSession[]> {\n const { data } = await this.httpClient.get<DeviceSession[]>(\"/auth/sessions/device\");\n return data;\n }\n\n async setActive(request: SetActiveSessionRequest): Promise<SetActiveSessionResponse> {\n const { data } = await this.httpClient.post<SetActiveSessionResponse>(\n \"/auth/sessions/set-active\",\n request,\n );\n await this.storeTokens(data.accessToken, data.refreshToken);\n return data;\n }\n\n async revokeDeviceSession(request: {\n sessionToken: string;\n }): Promise<void> {\n await this.httpClient.delete(`/auth/sessions/device/${request.sessionToken}`);\n }\n\n // --- Device Summary (T03-007) ---\n\n async getCurrentDevice(): Promise<DeviceSummary | null> {\n const session = await this.getCurrent();\n return session.device ?? null;\n }\n}\n","// Cookie Storage Adapter — document.cookie wrapper with options\n\nimport type { ITokenStorage } from \"./types\";\n\nexport interface CookieStorageOptions {\n secure?: boolean;\n sameSite?: \"strict\" | \"lax\" | \"none\";\n domain?: string;\n path?: string;\n maxAge?: number;\n}\n\nexport class CookieStorage implements ITokenStorage {\n private readonly secure: boolean;\n private readonly sameSite: \"strict\" | \"lax\" | \"none\";\n private readonly domain?: string;\n private readonly path: string;\n private readonly maxAge?: number;\n\n constructor(options?: CookieStorageOptions) {\n this.secure = options?.secure ?? true;\n this.sameSite = options?.sameSite ?? \"lax\";\n this.domain = options?.domain;\n this.path = options?.path ?? \"/\";\n this.maxAge = options?.maxAge;\n }\n\n async get(key: string): Promise<string | null> {\n if (typeof document === \"undefined\") return null;\n\n const cookies = document.cookie.split(\";\");\n for (const cookie of cookies) {\n const [cookieKey, ...cookieValueParts] = cookie.trim().split(\"=\");\n if (cookieKey === key) {\n const value = cookieValueParts.join(\"=\");\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n }\n }\n return null;\n }\n\n async set(key: string, value: string): Promise<void> {\n if (typeof document === \"undefined\") return;\n\n let cookie = `${key}=${encodeURIComponent(value)}`;\n cookie += `; path=${this.path}`;\n cookie += `; SameSite=${capitalize(this.sameSite)}`;\n\n if (this.secure) {\n cookie += \"; Secure\";\n }\n if (this.domain) {\n cookie += `; Domain=${this.domain}`;\n }\n if (this.maxAge !== undefined) {\n cookie += `; Max-Age=${this.maxAge}`;\n }\n\n document.cookie = cookie;\n }\n\n async remove(key: string): Promise<void> {\n if (typeof document === \"undefined\") return;\n\n let cookie = `${key}=; path=${this.path}; Max-Age=0`;\n if (this.domain) {\n cookie += `; Domain=${this.domain}`;\n }\n document.cookie = cookie;\n }\n}\n\nfunction capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n","// localStorage Adapter — SSR-safe wrapper\n\nimport type { ITokenStorage } from \"./types\";\n\nexport class LocalStorageAdapter implements ITokenStorage {\n async get(key: string): Promise<string | null> {\n if (typeof window === \"undefined\") return null;\n return window.localStorage.getItem(key);\n }\n\n async set(key: string, value: string): Promise<void> {\n if (typeof window === \"undefined\") return;\n window.localStorage.setItem(key, value);\n }\n\n async remove(key: string): Promise<void> {\n if (typeof window === \"undefined\") return;\n window.localStorage.removeItem(key);\n }\n}\n","// In-memory Token Storage — SSR-safe, default implementation\n\nimport type { ITokenStorage } from \"./types\";\n\nexport class MemoryStorage implements ITokenStorage {\n private store = new Map<string, string>();\n\n async get(key: string): Promise<string | null> {\n return this.store.get(key) ?? null;\n }\n\n async set(key: string, value: string): Promise<void> {\n this.store.set(key, value);\n }\n\n async remove(key: string): Promise<void> {\n this.store.delete(key);\n }\n}\n","// AuthClient — main entry point for @atzentis/auth-sdk\n\nimport { BrowserDeviceSignalCollector } from \"./device\";\nimport { HttpClient } from \"./http/client\";\nimport { createAuthInterceptor, createDeviceSignalInterceptor } from \"./http/interceptors\";\nimport { AuthService } from \"./services/auth\";\nimport { BackgroundRefresh } from \"./services/refresh\";\nimport { PhoneService } from \"./services/phone\";\nimport { SessionService } from \"./services/session\";\nimport { MemoryStorage } from \"./storage\";\nimport type { ITokenStorage } from \"./storage/types\";\nimport type {\n GetOAuthUrlRequest,\n LoginCredentials,\n LoginResponse,\n RefreshTokenResponse,\n RequestPasswordResetRequest,\n ResetPasswordRequest,\n ResetPasswordResponse,\n SendMagicLinkRequest,\n SendVerificationEmailRequest,\n SignupData,\n SignupResponse,\n UsernameLoginCredentials,\n VerifyEmailRequest,\n VerifyEmailResponse,\n VerifyMagicLinkRequest,\n VerifyOAuthCodeRequest,\n} from \"./types/auth\";\nimport type { AuthConfig } from \"./types/config\";\nimport { DEFAULT_REFRESH_TOKEN_STORAGE_KEY, DEFAULT_TOKEN_STORAGE_KEY } from \"./types/config\";\n\nconst RISK_ALERT_THRESHOLD = 30;\n\nexport class AuthClient {\n private readonly config: AuthConfig;\n private readonly httpClient: HttpClient;\n private readonly storage: ITokenStorage;\n private readonly authService: AuthService;\n private readonly backgroundRefresh: BackgroundRefresh;\n\n readonly phone: PhoneService;\n readonly sessions: SessionService;\n\n constructor(config: AuthConfig) {\n this.config = config;\n this.storage = config.storage ?? new MemoryStorage();\n\n const tokenStorageKey = config.tokenStorageKey ?? DEFAULT_TOKEN_STORAGE_KEY;\n const refreshTokenStorageKey = config.tokenStorageKey\n ? `${config.tokenStorageKey}_refresh`\n : DEFAULT_REFRESH_TOKEN_STORAGE_KEY;\n\n this.httpClient = new HttpClient({\n baseUrl: config.baseUrl,\n timeout: config.timeout,\n });\n\n // Add auth interceptor for API key\n const storage = this.storage;\n this.httpClient.addRequestInterceptor(\n createAuthInterceptor({\n tokenProvider: () => null,\n apiKey: config.apiKey,\n }),\n );\n\n // Auth interceptor with async token access\n this.httpClient.addRequestInterceptor(async (request) => {\n if (request.skipAuth) return request;\n const token = await storage.get(tokenStorageKey);\n if (token) {\n return {\n ...request,\n headers: {\n ...request.headers,\n Authorization: `Bearer ${token}`,\n },\n };\n }\n return request;\n });\n\n // Add device signal interceptor if enabled\n if (config.collectDeviceSignals !== false) {\n const collector = new BrowserDeviceSignalCollector();\n this.httpClient.addRequestInterceptor(createDeviceSignalInterceptor(collector));\n }\n\n this.authService = new AuthService(this.httpClient, this.storage, {\n tokenStorageKey,\n refreshTokenStorageKey,\n });\n\n this.phone = new PhoneService(\n this.httpClient,\n (accessToken, refreshToken) => this.authService.storeTokens(accessToken, refreshToken),\n (method) => this.authService.setLastLoginMethod(method),\n );\n\n this.sessions = new SessionService(this.httpClient, (accessToken, refreshToken) =>\n this.authService.storeTokens(accessToken, refreshToken),\n );\n\n this.backgroundRefresh = new BackgroundRefresh(\n async () => {\n const result = await this.authService.refreshToken();\n return { accessToken: result.accessToken, expiresIn: result.expiresIn };\n },\n config.refreshThreshold ?? 300,\n {\n onTokenRefreshed: config.onTokenRefreshed,\n onSessionExpired: config.onSessionExpired,\n },\n );\n }\n\n // --- Email/Password (T02-001) ---\n\n async login(credentials: LoginCredentials): Promise<LoginResponse> {\n const response = await this.authService.login(credentials);\n this.handleLoginEvent(response);\n this.startRefreshIfEnabled(response.expiresIn);\n return response;\n }\n\n async signup(data: SignupData): Promise<SignupResponse> {\n const response = await this.authService.signup(data);\n this.startRefreshIfEnabled(response.expiresIn);\n return response;\n }\n\n // --- Username (T02-002) ---\n\n async loginWithUsername(credentials: UsernameLoginCredentials): Promise<LoginResponse> {\n const response = await this.authService.loginWithUsername(credentials);\n this.handleLoginEvent(response);\n this.startRefreshIfEnabled(response.expiresIn);\n return response;\n }\n\n async isUsernameAvailable(username: string): Promise<boolean> {\n return this.authService.isUsernameAvailable(username);\n }\n\n // --- OAuth (T02-004) ---\n\n getOAuthUrl(request: GetOAuthUrlRequest): string {\n return this.authService.getOAuthUrl(request);\n }\n\n async verifyOAuthCode(request: VerifyOAuthCodeRequest): Promise<LoginResponse> {\n const response = await this.authService.verifyOAuthCode(request);\n this.handleLoginEvent(response);\n this.startRefreshIfEnabled(response.expiresIn);\n return response;\n }\n\n // --- Magic Link (T02-005) ---\n\n async sendMagicLink(request: SendMagicLinkRequest): Promise<void> {\n return this.authService.sendMagicLink(request);\n }\n\n async verifyMagicLink(request: VerifyMagicLinkRequest): Promise<LoginResponse> {\n const response = await this.authService.verifyMagicLink(request);\n this.handleLoginEvent(response);\n this.startRefreshIfEnabled(response.expiresIn);\n return response;\n }\n\n // --- Email Verification (T02-006) ---\n\n async sendVerificationEmail(request: SendVerificationEmailRequest): Promise<void> {\n return this.authService.sendVerificationEmail(request);\n }\n\n async verifyEmail(request: VerifyEmailRequest): Promise<VerifyEmailResponse> {\n return this.authService.verifyEmail(request);\n }\n\n // --- Password Reset (T02-007) ---\n\n async requestPasswordReset(request: RequestPasswordResetRequest): Promise<void> {\n return this.authService.requestPasswordReset(request);\n }\n\n async resetPassword(request: ResetPasswordRequest): Promise<ResetPasswordResponse> {\n return this.authService.resetPassword(request);\n }\n\n // --- Token Management (T02-009) ---\n\n async getAccessToken(): Promise<string | null> {\n return this.authService.getAccessToken();\n }\n\n async refreshToken(): Promise<RefreshTokenResponse> {\n return this.authService.refreshToken();\n }\n\n async isAuthenticated(): Promise<boolean> {\n return this.authService.isAuthenticated();\n }\n\n async getLastLoginMethod(): Promise<string | null> {\n return this.authService.getLastLoginMethod();\n }\n\n // --- Logout (T02-010) ---\n\n async logout(): Promise<void> {\n this.backgroundRefresh.stop();\n await this.authService.logout();\n this.config.onSessionExpired?.();\n }\n\n async logoutAllDevices(): Promise<void> {\n this.backgroundRefresh.stop();\n await this.authService.logoutAllDevices();\n this.config.onSessionExpired?.();\n }\n\n // --- Private ---\n\n private startRefreshIfEnabled(expiresIn: number): void {\n if (this.config.autoRefreshToken !== false) {\n this.backgroundRefresh.start(expiresIn);\n }\n }\n\n private handleLoginEvent(response: LoginResponse): void {\n if (\n response.loginEvent &&\n response.loginEvent.riskScore >= RISK_ALERT_THRESHOLD &&\n this.config.onNewDeviceAlert\n ) {\n const event = response.loginEvent;\n this.config.onNewDeviceAlert({\n deviceName: event.deviceName,\n deviceType: event.deviceType,\n city: event.city,\n country: event.country,\n riskScore: event.riskScore,\n });\n }\n }\n}\n","// Session Types v2.0\n\nimport type { User } from \"./user\";\n\n// --- Session ---\n\nexport interface Session {\n id: string;\n userId: string;\n organizationId: string;\n createdAt: string;\n expiresAt: string;\n ip: string;\n userAgent: string;\n device?: DeviceSummary;\n lastActivityAt?: string;\n}\n\n// --- Device Summary (v2.0) ---\n\nexport interface DeviceSummary {\n id: string;\n name: string;\n deviceType: \"mobile\" | \"desktop\" | \"tablet\";\n isTrusted: boolean;\n}\n\n// --- List Sessions ---\n\nexport interface ListSessionsRequest {\n limit?: number;\n offset?: number;\n}\n\nexport interface ListSessionsResponse {\n data: Session[];\n total: number;\n limit: number;\n offset: number;\n}\n\n// --- Revoke All ---\n\nexport interface RevokeAllSessionsOptions {\n exceptCurrent?: boolean;\n}\n\nexport interface RevokeAllSessionsResponse {\n revokedCount: number;\n}\n\n// --- Multi-Session (v2.0) ---\n\nexport interface DeviceSession {\n sessionToken: string;\n user: User;\n isActive: boolean;\n productId?: string;\n createdAt: string;\n}\n\nexport interface SetActiveSessionRequest {\n sessionToken: string;\n}\n\nexport interface SetActiveSessionResponse {\n accessToken: string;\n refreshToken: string;\n expiresIn: number;\n user: User;\n}\n\n// --- Type Guard ---\n\nexport function hasDevice(session: Session): session is Session & { device: DeviceSummary } {\n return session.device !== undefined;\n}\n","// Auth SDK Error Codes v2.0\n\nexport enum AuthErrorCode {\n // Authentication\n InvalidCredentials = \"INVALID_CREDENTIALS\",\n EmailNotVerified = \"EMAIL_NOT_VERIFIED\",\n TwoFactorRequired = \"TWO_FACTOR_REQUIRED\",\n\n // Phone Auth (v2.0)\n InvalidPhoneNumber = \"INVALID_PHONE_NUMBER\",\n OTPExpired = \"OTP_EXPIRED\",\n OTPInvalid = \"OTP_INVALID\",\n OTPMaxAttempts = \"OTP_MAX_ATTEMPTS\",\n PhoneNumberInUse = \"PHONE_NUMBER_IN_USE\",\n FraudDetected = \"FRAUD_DETECTED\",\n\n // Username (v2.0)\n UsernameTaken = \"USERNAME_TAKEN\",\n UsernameInvalid = \"USERNAME_INVALID\",\n UsernameReserved = \"USERNAME_RESERVED\",\n\n // Device / Login Activity (v2.0)\n DeviceNotFound = \"DEVICE_NOT_FOUND\",\n LoginEventNotFound = \"LOGIN_EVENT_NOT_FOUND\",\n ReauthRequired = \"REAUTH_REQUIRED\",\n\n // Multi-session (v2.0)\n MaxSessionsExceeded = \"MAX_SESSIONS_EXCEEDED\",\n\n // CAPTCHA (v2.0)\n CaptchaRequired = \"CAPTCHA_REQUIRED\",\n CaptchaInvalid = \"CAPTCHA_INVALID\",\n\n // Breach (v2.0)\n PasswordBreached = \"PASSWORD_BREACHED\",\n\n // Session / Token\n SessionExpired = \"SESSION_EXPIRED\",\n TokenExpired = \"TOKEN_EXPIRED\",\n InvalidToken = \"INVALID_TOKEN\",\n\n // Authorization\n UnauthorizedRole = \"UNAUTHORIZED_ROLE\",\n OrganizationNotFound = \"ORGANIZATION_NOT_FOUND\",\n PermissionDenied = \"PERMISSION_DENIED\",\n\n // Rate Limiting & Network\n RateLimited = \"RATE_LIMITED\",\n NetworkError = \"NETWORK_ERROR\",\n Timeout = \"TIMEOUT\",\n\n // User Management\n UserNotFound = \"USER_NOT_FOUND\",\n UserAlreadyExists = \"USER_ALREADY_EXISTS\",\n InvalidEmail = \"INVALID_EMAIL\",\n WeakPassword = \"WEAK_PASSWORD\",\n\n // Organization\n OrganizationLimitExceeded = \"ORG_LIMIT_EXCEEDED\",\n MemberLimitExceeded = \"MEMBER_LIMIT_EXCEEDED\",\n\n // API Keys\n KeyNotFound = \"KEY_NOT_FOUND\",\n KeyRevoked = \"KEY_REVOKED\",\n KeyExpired = \"KEY_EXPIRED\",\n}\n"]}
1
+ {"version":3,"sources":["../src/device/browser-collector.ts","../src/errors/auth-error.ts","../src/errors/errors.ts","../src/errors/factory.ts","../src/http/rate-limit.ts","../src/http/retry.ts","../src/http/client.ts","../src/http/interceptors/auth.ts","../src/http/interceptors/device-signals.ts","../src/types/config.ts","../src/services/validators.ts","../src/services/auth.ts","../src/services/device.ts","../src/services/login-activity.ts","../src/services/organization.ts","../src/services/phone.ts","../src/services/refresh.ts","../src/services/session.ts","../src/storage/cookie-storage.ts","../src/storage/local-storage-adapter.ts","../src/storage/memory-storage.ts","../src/types/device.ts","../src/client.ts","../src/types/session.ts","../src/errors/codes.ts"],"names":["AuthErrorCode"],"mappings":"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","file":"index.js","sourcesContent":["// Browser Device Signal Collector — SSR-safe\n\nimport type { DeviceSignals, IDeviceSignalCollector } from \"./types\";\n\nconst EMPTY_SIGNALS: DeviceSignals = {\n screen: \"\",\n timezone: \"\",\n platform: \"\",\n language: \"\",\n colorDepth: \"\",\n touchSupport: \"\",\n};\n\nfunction simpleHash(input: string): string {\n let hash = 0;\n for (let i = 0; i < input.length; i++) {\n const char = input.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash |= 0;\n }\n return Math.abs(hash).toString(16).padStart(8, \"0\");\n}\n\nasync function sha256Hash(input: string): Promise<string> {\n try {\n if (typeof globalThis.crypto?.subtle?.digest === \"function\") {\n const encoder = new TextEncoder();\n const data = encoder.encode(input);\n const hashBuffer = await globalThis.crypto.subtle.digest(\"SHA-256\", data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n }\n } catch {\n // Fallback below\n }\n return simpleHash(input);\n}\n\nexport class BrowserDeviceSignalCollector implements IDeviceSignalCollector {\n private cached: DeviceSignals | null = null;\n private cachedFingerprint: string | null = null;\n\n async collect(): Promise<DeviceSignals> {\n if (this.cached) return this.cached;\n\n if (typeof window === \"undefined\" || typeof navigator === \"undefined\") {\n this.cached = EMPTY_SIGNALS;\n return this.cached;\n }\n\n this.cached = {\n screen: `${screen.width}x${screen.height}`,\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n platform: navigator.platform,\n language: navigator.language,\n colorDepth: String(screen.colorDepth),\n touchSupport: String(\"ontouchstart\" in window),\n };\n\n return this.cached;\n }\n\n async getFingerprint(): Promise<string> {\n if (this.cachedFingerprint) return this.cachedFingerprint;\n\n const signals = await this.collect();\n const raw = [\n signals.screen,\n signals.timezone,\n signals.platform,\n signals.language,\n signals.colorDepth,\n signals.touchSupport,\n ].join(\"|\");\n\n this.cachedFingerprint = await sha256Hash(raw);\n return this.cachedFingerprint;\n }\n}\n","// Base Auth Error\n\nimport type { AuthErrorCode } from \"./codes\";\n\nexport interface AuthErrorOptions {\n code: AuthErrorCode;\n message: string;\n statusCode: number;\n details?: Record<string, unknown>;\n requestId?: string;\n}\n\nexport class AuthError extends Error {\n readonly code: AuthErrorCode;\n readonly statusCode: number;\n readonly details?: Record<string, unknown>;\n readonly requestId?: string;\n\n constructor(options: AuthErrorOptions) {\n super(options.message);\n this.name = \"AuthError\";\n this.code = options.code;\n this.statusCode = options.statusCode;\n this.details = options.details;\n this.requestId = options.requestId;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n toJSON(): Record<string, unknown> {\n return {\n code: this.code,\n message: this.message,\n statusCode: this.statusCode,\n details: this.details,\n requestId: this.requestId,\n };\n }\n}\n","// Error Subclasses\n\nimport { AuthError, type AuthErrorOptions } from \"./auth-error\";\nimport type { AuthErrorCode } from \"./codes\";\n\ntype SubclassOptions = Omit<AuthErrorOptions, \"statusCode\"> & { statusCode?: number };\n\nexport class ValidationError extends AuthError {\n constructor(options: SubclassOptions) {\n super({ ...options, statusCode: options.statusCode ?? 400 });\n this.name = \"ValidationError\";\n }\n}\n\nexport class AuthenticationError extends AuthError {\n constructor(options: SubclassOptions) {\n super({ ...options, statusCode: options.statusCode ?? 401 });\n this.name = \"AuthenticationError\";\n }\n}\n\nexport class ForbiddenError extends AuthError {\n constructor(options: SubclassOptions) {\n super({ ...options, statusCode: options.statusCode ?? 403 });\n this.name = \"ForbiddenError\";\n }\n}\n\nexport class NotFoundError extends AuthError {\n constructor(options: SubclassOptions) {\n super({ ...options, statusCode: options.statusCode ?? 404 });\n this.name = \"NotFoundError\";\n }\n}\n\nexport class ConflictError extends AuthError {\n constructor(options: SubclassOptions) {\n super({ ...options, statusCode: options.statusCode ?? 409 });\n this.name = \"ConflictError\";\n }\n}\n\nexport class UnprocessableError extends AuthError {\n constructor(options: SubclassOptions) {\n super({ ...options, statusCode: options.statusCode ?? 422 });\n this.name = \"UnprocessableError\";\n }\n}\n\nexport interface RateLimitErrorOptions extends SubclassOptions {\n retryAfter: number;\n}\n\nexport class RateLimitError extends AuthError {\n readonly retryAfter: number;\n\n constructor(options: RateLimitErrorOptions) {\n super({ ...options, statusCode: options.statusCode ?? 429 });\n this.name = \"RateLimitError\";\n this.retryAfter = options.retryAfter;\n }\n\n override toJSON(): Record<string, unknown> {\n return { ...super.toJSON(), retryAfter: this.retryAfter };\n }\n}\n\nexport class ServerError extends AuthError {\n constructor(options: SubclassOptions) {\n super({ ...options, statusCode: options.statusCode ?? 500 });\n this.name = \"ServerError\";\n }\n}\n\nexport interface NetworkErrorOptions {\n message: string;\n code?: AuthErrorCode;\n details?: Record<string, unknown>;\n requestId?: string;\n}\n\nexport class NetworkError extends AuthError {\n constructor(options: NetworkErrorOptions) {\n super({\n code: options.code ?? (\"NETWORK_ERROR\" as AuthErrorCode),\n message: options.message,\n statusCode: 0,\n details: options.details,\n requestId: options.requestId,\n });\n this.name = \"NetworkError\";\n }\n}\n\nexport interface TimeoutErrorOptions {\n duration: number;\n message?: string;\n requestId?: string;\n}\n\nexport class TimeoutError extends AuthError {\n readonly duration: number;\n\n constructor(options: TimeoutErrorOptions) {\n super({\n code: \"TIMEOUT\" as AuthErrorCode,\n message: options.message ?? `Request timed out after ${options.duration}ms`,\n statusCode: 0,\n requestId: options.requestId,\n });\n this.name = \"TimeoutError\";\n this.duration = options.duration;\n }\n\n override toJSON(): Record<string, unknown> {\n return { ...super.toJSON(), duration: this.duration };\n }\n}\n","// Error Factory — maps HTTP responses to typed errors\n\nimport { AuthError } from \"./auth-error\";\nimport type { AuthErrorCode } from \"./codes\";\nimport {\n AuthenticationError,\n ConflictError,\n ForbiddenError,\n NotFoundError,\n RateLimitError,\n ServerError,\n UnprocessableError,\n ValidationError,\n} from \"./errors\";\n\ninterface ErrorBody {\n code?: string;\n message?: string;\n details?: Record<string, unknown>;\n}\n\nfunction parseBody(body: unknown): ErrorBody {\n if (body && typeof body === \"object\" && \"message\" in body) {\n const obj = body as Record<string, unknown>;\n return {\n code: typeof obj.code === \"string\" ? obj.code : undefined,\n message: typeof obj.message === \"string\" ? obj.message : \"Unknown error\",\n details:\n typeof obj.details === \"object\" && obj.details !== null\n ? (obj.details as Record<string, unknown>)\n : undefined,\n };\n }\n return { message: \"Unknown error\" };\n}\n\nexport function parseRetryAfterHeader(header: string | null): number {\n if (!header) return 60;\n\n const seconds = Number(header);\n if (!Number.isNaN(seconds)) return seconds;\n\n const date = new Date(header);\n if (!Number.isNaN(date.getTime())) {\n return Math.max(0, Math.ceil((date.getTime() - Date.now()) / 1000));\n }\n\n return 60;\n}\n\nexport function createErrorFromResponse(\n status: number,\n body: unknown,\n headers: Headers,\n): AuthError {\n const parsed = parseBody(body);\n const requestId = headers.get(\"x-request-id\") ?? undefined;\n const code = (parsed.code ?? \"NETWORK_ERROR\") as AuthErrorCode;\n const message = parsed.message ?? `HTTP ${status}`;\n const details = parsed.details;\n const base = { code, message, details, requestId };\n\n switch (true) {\n case status === 400:\n return new ValidationError(base);\n case status === 401:\n return new AuthenticationError(base);\n case status === 403:\n return new ForbiddenError(base);\n case status === 404:\n return new NotFoundError(base);\n case status === 409:\n return new ConflictError(base);\n case status === 422:\n return new UnprocessableError(base);\n case status === 429: {\n const retryAfter = parseRetryAfterHeader(headers.get(\"retry-after\"));\n return new RateLimitError({ ...base, retryAfter });\n }\n case status >= 500 && status < 600:\n return new ServerError(base);\n default:\n return new AuthError({ ...base, statusCode: status });\n }\n}\n","// Rate Limit Handling\n\nimport type { RateLimitConfig } from \"./types\";\n\nexport const DEFAULT_RATE_LIMIT_CONFIG: RateLimitConfig = {\n autoRetry: true,\n maxRetryAfter: 60,\n};\n\nexport function mergeRateLimitConfig(config?: Partial<RateLimitConfig>): RateLimitConfig {\n return { ...DEFAULT_RATE_LIMIT_CONFIG, ...config };\n}\n\nexport function parseRetryAfter(header: string | null): number {\n if (!header) return 60;\n\n const seconds = Number(header);\n if (!Number.isNaN(seconds)) return seconds;\n\n const date = new Date(header);\n if (!Number.isNaN(date.getTime())) {\n return Math.max(0, Math.ceil((date.getTime() - Date.now()) / 1000));\n }\n\n return 60;\n}\n","// Retry Logic with Exponential Backoff\n\nimport type { RetryConfig } from \"./types\";\n\nexport const DEFAULT_RETRY_CONFIG: RetryConfig = {\n maxRetries: 3,\n baseDelay: 1000,\n maxDelay: 10000,\n factor: 2,\n jitter: true,\n retryableStatuses: [500, 502, 503, 504],\n retryPost: false,\n};\n\nexport function mergeRetryConfig(config?: Partial<RetryConfig>): RetryConfig {\n return { ...DEFAULT_RETRY_CONFIG, ...config };\n}\n\nexport function shouldRetry(\n error: unknown,\n attempt: number,\n method: string,\n config: RetryConfig,\n): boolean {\n if (attempt >= config.maxRetries) return false;\n if (method === \"POST\" && !config.retryPost) return false;\n\n // Network error (TypeError from fetch)\n if (error instanceof TypeError) return true;\n\n // Check statusCode on error objects\n if (error && typeof error === \"object\" && \"statusCode\" in error) {\n const statusCode = (error as { statusCode: number }).statusCode;\n return config.retryableStatuses.includes(statusCode);\n }\n\n return false;\n}\n\nexport function calculateDelay(attempt: number, config: RetryConfig): number {\n const exponential = config.baseDelay * config.factor ** attempt;\n const delay = Math.min(exponential, config.maxDelay);\n\n if (!config.jitter) return delay;\n\n return Math.round(delay * Math.random());\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","// HTTP Client — zero-dependency fetch wrapper\n\nimport { NetworkError, RateLimitError, TimeoutError } from \"../errors/errors\";\nimport { createErrorFromResponse } from \"../errors/factory\";\nimport { mergeRateLimitConfig } from \"./rate-limit\";\nimport { calculateDelay, mergeRetryConfig, shouldRetry, sleep } from \"./retry\";\nimport type {\n ApiResponse,\n ErrorInterceptor,\n HttpClientConfig,\n RateLimitConfig,\n RequestConfig,\n RequestInterceptor,\n ResponseInterceptor,\n RetryConfig,\n} from \"./types\";\n\nexport class HttpClient {\n private readonly config: HttpClientConfig;\n private readonly retryConfig: RetryConfig;\n private readonly rateLimitConfig: RateLimitConfig;\n private requestInterceptors: RequestInterceptor[] = [];\n private responseInterceptors: ResponseInterceptor[] = [];\n private errorInterceptors: ErrorInterceptor[] = [];\n\n constructor(config: HttpClientConfig) {\n this.config = config;\n this.retryConfig = mergeRetryConfig(config.retry);\n this.rateLimitConfig = mergeRateLimitConfig(config.rateLimit);\n }\n\n // --- Public HTTP Methods ---\n\n async get<T>(\n path: string,\n config?: Partial<Omit<RequestConfig, \"method\" | \"path\" | \"body\">>,\n ): Promise<ApiResponse<T>> {\n return this.request<T>({ ...config, method: \"GET\", path });\n }\n\n async post<T>(\n path: string,\n body?: unknown,\n config?: Partial<Omit<RequestConfig, \"method\" | \"path\" | \"body\">>,\n ): Promise<ApiResponse<T>> {\n return this.request<T>({ ...config, method: \"POST\", path, body });\n }\n\n async put<T>(\n path: string,\n body?: unknown,\n config?: Partial<Omit<RequestConfig, \"method\" | \"path\" | \"body\">>,\n ): Promise<ApiResponse<T>> {\n return this.request<T>({ ...config, method: \"PUT\", path, body });\n }\n\n async patch<T>(\n path: string,\n body?: unknown,\n config?: Partial<Omit<RequestConfig, \"method\" | \"path\" | \"body\">>,\n ): Promise<ApiResponse<T>> {\n return this.request<T>({ ...config, method: \"PATCH\", path, body });\n }\n\n async delete<T>(\n path: string,\n config?: Partial<Omit<RequestConfig, \"method\" | \"path\" | \"body\">>,\n ): Promise<ApiResponse<T>> {\n return this.request<T>({ ...config, method: \"DELETE\", path });\n }\n\n getBaseUrl(): string {\n return this.config.baseUrl;\n }\n\n // --- Interceptor Management ---\n\n addRequestInterceptor(fn: RequestInterceptor): void {\n this.requestInterceptors.push(fn);\n }\n\n removeRequestInterceptor(fn: RequestInterceptor): void {\n this.requestInterceptors = this.requestInterceptors.filter((i) => i !== fn);\n }\n\n addResponseInterceptor(fn: ResponseInterceptor): void {\n this.responseInterceptors.push(fn);\n }\n\n removeResponseInterceptor(fn: ResponseInterceptor): void {\n this.responseInterceptors = this.responseInterceptors.filter((i) => i !== fn);\n }\n\n addErrorInterceptor(fn: ErrorInterceptor): void {\n this.errorInterceptors.push(fn);\n }\n\n removeErrorInterceptor(fn: ErrorInterceptor): void {\n this.errorInterceptors = this.errorInterceptors.filter((i) => i !== fn);\n }\n\n // --- Internal ---\n\n private async request<T>(initialConfig: RequestConfig): Promise<ApiResponse<T>> {\n // Run request interceptors\n let config = { ...initialConfig };\n for (const interceptor of this.requestInterceptors) {\n config = await interceptor(config);\n }\n\n // Build URL\n const url = new URL(config.path, this.config.baseUrl);\n if (config.params) {\n for (const [key, value] of Object.entries(config.params)) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n // Build headers\n const headers: Record<string, string> = {\n ...this.config.headers,\n ...config.headers,\n };\n if (config.body !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n // Retry loop\n const maxAttempts = this.retryConfig.maxRetries + 1;\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n return await this.executeFetch<T>(url, headers, config, attempt);\n } catch (error) {\n // Run error interceptors\n let processedError = error;\n for (const interceptor of this.errorInterceptors) {\n processedError = await interceptor(processedError);\n }\n\n // Rate limit: handle 429 separately from general retry\n if (processedError instanceof RateLimitError) {\n if (\n this.rateLimitConfig.autoRetry &&\n processedError.retryAfter <= this.rateLimitConfig.maxRetryAfter &&\n attempt === 0\n ) {\n await sleep(processedError.retryAfter * 1000);\n continue;\n }\n throw processedError;\n }\n\n // General retry\n if (shouldRetry(processedError, attempt, config.method, this.retryConfig)) {\n const delay = calculateDelay(attempt, this.retryConfig);\n await sleep(delay);\n continue;\n }\n\n throw processedError;\n }\n }\n\n // Should not reach here, but satisfy TypeScript\n throw new NetworkError({ message: \"Max retries exceeded\" });\n }\n\n private async executeFetch<T>(\n url: URL,\n headers: Record<string, string>,\n config: RequestConfig,\n _attempt: number,\n ): Promise<ApiResponse<T>> {\n const timeout = config.timeout ?? this.config.timeout ?? 30_000;\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(url.toString(), {\n method: config.method,\n headers,\n body: config.body !== undefined ? JSON.stringify(config.body) : undefined,\n signal: config.signal ?? controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n // Handle error responses\n if (!response.ok) {\n let body: unknown;\n try {\n body = await response.json();\n } catch {\n body = { message: response.statusText };\n }\n throw createErrorFromResponse(response.status, body, response.headers);\n }\n\n // Parse successful response\n let data: T;\n if (response.status === 204) {\n data = undefined as T;\n } else {\n data = (await response.json()) as T;\n }\n\n let result: ApiResponse<unknown> = {\n data,\n status: response.status,\n headers: response.headers,\n };\n\n // Run response interceptors\n for (const interceptor of this.responseInterceptors) {\n result = await interceptor(result);\n }\n\n return result as ApiResponse<T>;\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof DOMException && error.name === \"AbortError\") {\n throw new TimeoutError({ duration: timeout });\n }\n\n if (error instanceof TypeError) {\n throw new NetworkError({ message: error.message });\n }\n\n throw error;\n }\n }\n}\n","// Auth Header Interceptor\n\nimport type { RequestInterceptor } from \"../types\";\n\nexport interface AuthInterceptorConfig {\n tokenProvider?: () => string | null;\n apiKey?: string;\n}\n\nexport function createAuthInterceptor(config: AuthInterceptorConfig): RequestInterceptor {\n return (request) => {\n if (request.skipAuth) return request;\n\n const headers = { ...request.headers };\n\n if (config.tokenProvider) {\n const token = config.tokenProvider();\n if (token) {\n headers.Authorization = `Bearer ${token}`;\n }\n }\n\n if (config.apiKey) {\n headers[\"x-api-key\"] = config.apiKey;\n }\n\n return { ...request, headers };\n };\n}\n","// Device Signal Header Interceptor\n\nimport type { IDeviceSignalCollector } from \"../../device/types\";\nimport type { RequestInterceptor } from \"../types\";\n\nexport function createDeviceSignalInterceptor(\n collector: IDeviceSignalCollector,\n): RequestInterceptor {\n return async (request) => {\n const signals = await collector.collect();\n\n // Skip if no signals collected (SSR)\n if (!signals.screen && !signals.timezone && !signals.platform) {\n return request;\n }\n\n const fingerprint = await collector.getFingerprint();\n\n const headers: Record<string, string> = {\n ...request.headers,\n \"x-device-screen\": signals.screen,\n \"x-device-timezone\": signals.timezone,\n \"x-device-platform\": signals.platform,\n \"x-device-language\": signals.language,\n \"x-device-color-depth\": signals.colorDepth,\n \"x-device-touch\": signals.touchSupport,\n \"x-device-fingerprint\": fingerprint,\n };\n\n return { ...request, headers };\n };\n}\n","// Auth Client Configuration v2.0\n\nimport type { ITokenStorage } from \"../storage/types\";\nimport type { LoginAlert } from \"./auth\";\n\nexport interface AuthConfig {\n // API Configuration\n apiKey?: string;\n baseUrl: string;\n timeout?: number;\n\n // Storage Configuration\n tokenStorageKey?: string;\n sessionStorageKey?: string;\n\n // Token Management\n autoRefreshToken?: boolean;\n refreshThreshold?: number;\n\n // v2.0: Device Signal Collection\n collectDeviceSignals?: boolean;\n\n // Callbacks\n onSessionExpired?: () => void;\n onTokenRefreshed?: (token: string) => void;\n onNewDeviceAlert?: (alert: LoginAlert) => void;\n\n // Platform-specific\n storage?: ITokenStorage;\n}\n\n// Storage key defaults\nexport const DEFAULT_TOKEN_STORAGE_KEY = \"atz_auth_token\";\nexport const DEFAULT_REFRESH_TOKEN_STORAGE_KEY = \"atz_refresh_token\";\nexport const DEFAULT_SESSION_STORAGE_KEY = \"atz_session\";\nexport const DEFAULT_LAST_LOGIN_METHOD_KEY = \"atz_last_login_method\";\n","// Client-side validation helpers\n\nimport { ValidationError } from \"../errors/errors\";\n\nconst USERNAME_MIN_LENGTH = 3;\nconst USERNAME_MAX_LENGTH = 20;\nconst USERNAME_PATTERN = /^[a-z0-9]+$/;\n\nconst PHONE_E164_PATTERN = /^\\+\\d{10,15}$/;\nconst SUPPORTED_COUNTRY_CODES = [\"+30\", \"+49\"];\n\nexport function validateUsername(username: string): void {\n if (username.length < USERNAME_MIN_LENGTH) {\n throw new ValidationError({\n code: \"USERNAME_INVALID\" as never,\n message: `Username must be at least ${USERNAME_MIN_LENGTH} characters`,\n });\n }\n if (username.length > USERNAME_MAX_LENGTH) {\n throw new ValidationError({\n code: \"USERNAME_INVALID\" as never,\n message: `Username must be at most ${USERNAME_MAX_LENGTH} characters`,\n });\n }\n if (!USERNAME_PATTERN.test(username)) {\n throw new ValidationError({\n code: \"USERNAME_INVALID\" as never,\n message: \"Username must contain only lowercase letters and numbers\",\n });\n }\n}\n\nexport function validatePhoneNumber(phoneNumber: string): void {\n if (!PHONE_E164_PATTERN.test(phoneNumber)) {\n throw new ValidationError({\n code: \"INVALID_PHONE_NUMBER\" as never,\n message: \"Phone number must be in E.164 format (e.g. +301234567890)\",\n });\n }\n const hasValidCountryCode = SUPPORTED_COUNTRY_CODES.some((code) => phoneNumber.startsWith(code));\n if (!hasValidCountryCode) {\n throw new ValidationError({\n code: \"INVALID_PHONE_NUMBER\" as never,\n message: `Phone number must start with one of: ${SUPPORTED_COUNTRY_CODES.join(\", \")}`,\n });\n }\n}\n","// Authentication Service\n\nimport type { HttpClient } from \"../http/client\";\nimport type { ITokenStorage } from \"../storage/types\";\nimport type {\n LoginCredentials,\n LoginResponse,\n RefreshTokenResponse,\n RequestPasswordResetRequest,\n ResetPasswordRequest,\n ResetPasswordResponse,\n SendMagicLinkRequest,\n SendVerificationEmailRequest,\n SignupData,\n SignupResponse,\n UsernameLoginCredentials,\n VerifyEmailRequest,\n VerifyEmailResponse,\n VerifyMagicLinkRequest,\n} from \"../types/auth\";\nimport {\n DEFAULT_LAST_LOGIN_METHOD_KEY,\n DEFAULT_REFRESH_TOKEN_STORAGE_KEY,\n DEFAULT_SESSION_STORAGE_KEY,\n DEFAULT_TOKEN_STORAGE_KEY,\n} from \"../types/config\";\nimport { validateUsername } from \"./validators\";\n\nexport class AuthService {\n private readonly httpClient: HttpClient;\n private readonly storage: ITokenStorage;\n private readonly tokenStorageKey: string;\n private readonly refreshTokenStorageKey: string;\n private readonly sessionStorageKey: string;\n private readonly lastLoginMethodKey: string;\n private refreshPromise: Promise<RefreshTokenResponse> | null = null;\n\n constructor(\n httpClient: HttpClient,\n storage: ITokenStorage,\n options?: {\n tokenStorageKey?: string;\n refreshTokenStorageKey?: string;\n sessionStorageKey?: string;\n lastLoginMethodKey?: string;\n },\n ) {\n this.httpClient = httpClient;\n this.storage = storage;\n this.tokenStorageKey = options?.tokenStorageKey ?? DEFAULT_TOKEN_STORAGE_KEY;\n this.refreshTokenStorageKey =\n options?.refreshTokenStorageKey ?? DEFAULT_REFRESH_TOKEN_STORAGE_KEY;\n this.sessionStorageKey = options?.sessionStorageKey ?? DEFAULT_SESSION_STORAGE_KEY;\n this.lastLoginMethodKey = options?.lastLoginMethodKey ?? DEFAULT_LAST_LOGIN_METHOD_KEY;\n }\n\n // --- Email/Password Login & Signup ---\n\n async login(credentials: LoginCredentials): Promise<LoginResponse> {\n const { data } = await this.httpClient.post<LoginResponse>(\"/auth/login\", credentials, {\n skipAuth: true,\n });\n\n await this.storeTokens(data.accessToken, data.refreshToken);\n await this.setLastLoginMethod(\"email\");\n\n return data;\n }\n\n async signup(data: SignupData): Promise<SignupResponse> {\n const { data: response } = await this.httpClient.post<SignupResponse>(\"/auth/signup\", data, {\n skipAuth: true,\n });\n\n await this.storeTokens(response.accessToken, response.refreshToken);\n await this.setLastLoginMethod(\"email\");\n\n return response;\n }\n\n // --- Username Login ---\n\n async loginWithUsername(credentials: UsernameLoginCredentials): Promise<LoginResponse> {\n validateUsername(credentials.username);\n\n const { data } = await this.httpClient.post<LoginResponse>(\n \"/auth/login/username\",\n credentials,\n { skipAuth: true },\n );\n\n await this.storeTokens(data.accessToken, data.refreshToken);\n await this.setLastLoginMethod(\"username\");\n\n return data;\n }\n\n async isUsernameAvailable(username: string): Promise<boolean> {\n validateUsername(username);\n\n const { data } = await this.httpClient.get<{ available: boolean }>(\"/auth/username/available\", {\n params: { username },\n });\n\n return data.available;\n }\n\n // --- OAuth ---\n\n getOAuthUrl(request: {\n provider: string;\n redirectUri: string;\n state: string;\n scopes?: string[];\n }): string {\n const baseUrl = this.httpClient.getBaseUrl();\n const params = new URLSearchParams({\n provider: request.provider,\n redirect_uri: request.redirectUri,\n state: request.state,\n });\n if (request.scopes?.length) {\n params.set(\"scopes\", request.scopes.join(\",\"));\n }\n return `${baseUrl}/auth/oauth/authorize?${params.toString()}`;\n }\n\n async verifyOAuthCode(request: {\n provider: string;\n code: string;\n redirectUri: string;\n }): Promise<LoginResponse> {\n const { data } = await this.httpClient.post<LoginResponse>(\"/auth/oauth/verify\", request, {\n skipAuth: true,\n });\n\n await this.storeTokens(data.accessToken, data.refreshToken);\n await this.setLastLoginMethod(\"oauth\");\n\n return data;\n }\n\n // --- Magic Link ---\n\n async sendMagicLink(request: SendMagicLinkRequest): Promise<void> {\n await this.httpClient.post(\"/auth/magic-link/send\", request, { skipAuth: true });\n }\n\n async verifyMagicLink(request: VerifyMagicLinkRequest): Promise<LoginResponse> {\n const { data } = await this.httpClient.post<LoginResponse>(\"/auth/magic-link/verify\", request, {\n skipAuth: true,\n });\n\n await this.storeTokens(data.accessToken, data.refreshToken);\n await this.setLastLoginMethod(\"magic_link\");\n\n return data;\n }\n\n // --- Email Verification ---\n\n async sendVerificationEmail(request: SendVerificationEmailRequest): Promise<void> {\n await this.httpClient.post(\"/auth/email/send-verification\", request);\n }\n\n async verifyEmail(request: VerifyEmailRequest): Promise<VerifyEmailResponse> {\n const { data } = await this.httpClient.post<VerifyEmailResponse>(\n \"/auth/email/verify\",\n request,\n { skipAuth: true },\n );\n return data;\n }\n\n // --- Password Reset ---\n\n async requestPasswordReset(request: RequestPasswordResetRequest): Promise<void> {\n await this.httpClient.post(\"/auth/password/reset-request\", request, { skipAuth: true });\n }\n\n async resetPassword(request: ResetPasswordRequest): Promise<ResetPasswordResponse> {\n const { data } = await this.httpClient.post<ResetPasswordResponse>(\n \"/auth/password/reset\",\n request,\n { skipAuth: true },\n );\n return data;\n }\n\n // --- Token Management ---\n\n async getAccessToken(): Promise<string | null> {\n return this.storage.get(this.tokenStorageKey);\n }\n\n async refreshToken(): Promise<RefreshTokenResponse> {\n if (this.refreshPromise) {\n return this.refreshPromise;\n }\n\n this.refreshPromise = this.executeRefresh();\n try {\n return await this.refreshPromise;\n } finally {\n this.refreshPromise = null;\n }\n }\n\n async isAuthenticated(): Promise<boolean> {\n const token = await this.storage.get(this.tokenStorageKey);\n if (!token) return false;\n\n const decoded = decodeJwtPayload(token);\n if (!decoded) return false;\n\n return decoded.exp * 1000 > Date.now();\n }\n\n async getLastLoginMethod(): Promise<string | null> {\n return this.storage.get(this.lastLoginMethodKey);\n }\n\n // --- Logout ---\n\n async logout(): Promise<void> {\n try {\n await this.httpClient.post(\"/auth/logout\", {});\n } catch {\n // Fire-and-forget: always clear tokens even if API call fails\n }\n await this.clearTokens();\n }\n\n async logoutAllDevices(): Promise<void> {\n try {\n await this.httpClient.post(\"/auth/logout/all\", {});\n } catch {\n // Fire-and-forget: always clear tokens even if API call fails\n }\n await this.clearTokens();\n }\n\n // --- Storage Helpers ---\n\n async storeTokens(accessToken: string, refreshToken: string): Promise<void> {\n await this.storage.set(this.tokenStorageKey, accessToken);\n await this.storage.set(this.refreshTokenStorageKey, refreshToken);\n }\n\n async setLastLoginMethod(method: string): Promise<void> {\n await this.storage.set(this.lastLoginMethodKey, method);\n }\n\n async clearTokens(): Promise<void> {\n await this.storage.remove(this.tokenStorageKey);\n await this.storage.remove(this.refreshTokenStorageKey);\n await this.storage.remove(this.sessionStorageKey);\n await this.storage.remove(this.lastLoginMethodKey);\n }\n\n // --- Private ---\n\n private async executeRefresh(): Promise<RefreshTokenResponse> {\n const currentRefreshToken = await this.storage.get(this.refreshTokenStorageKey);\n const { data } = await this.httpClient.post<RefreshTokenResponse>(\"/auth/token/refresh\", {\n refreshToken: currentRefreshToken,\n });\n await this.storeTokens(data.accessToken, data.refreshToken);\n return data;\n }\n}\n\n// --- JWT Decode Utility ---\n\nexport function decodeJwtPayload(token: string): {\n sub: string;\n email: string;\n name: string;\n exp: number;\n iat: number;\n org?: string;\n roles?: string[];\n} | null {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n\n const payload = parts[1];\n // Base64url to base64\n const base64 = payload.replace(/-/g, \"+\").replace(/_/g, \"/\");\n // Pad if needed\n const padded = base64 + \"=\".repeat((4 - (base64.length % 4)) % 4);\n const decoded = atob(padded);\n return JSON.parse(decoded);\n } catch {\n return null;\n }\n}\n","// Device Service — device management\n\nimport type { HttpClient } from \"../http/client\";\nimport type { Device, ListDevicesResponse, RemoveAllOtherDevicesResponse } from \"../types/device\";\n\nexport class DeviceService {\n private readonly httpClient: HttpClient;\n\n constructor(httpClient: HttpClient) {\n this.httpClient = httpClient;\n }\n\n async list(): Promise<ListDevicesResponse> {\n const { data } = await this.httpClient.get<ListDevicesResponse>(\"/auth/devices\");\n return data;\n }\n\n async getCurrent(): Promise<Device> {\n const { data } = await this.httpClient.get<Device>(\"/auth/devices/current\");\n return data;\n }\n\n async trust(deviceId: string): Promise<void> {\n await this.httpClient.post(`/auth/devices/${deviceId}/trust`);\n }\n\n async untrust(deviceId: string): Promise<void> {\n await this.httpClient.post(`/auth/devices/${deviceId}/untrust`);\n }\n\n async remove(deviceId: string): Promise<void> {\n await this.httpClient.delete(`/auth/devices/${deviceId}`);\n }\n\n async removeAllOthers(): Promise<RemoveAllOtherDevicesResponse> {\n const { data } = await this.httpClient.post<RemoveAllOtherDevicesResponse>(\n \"/auth/devices/remove-all-others\",\n );\n return data;\n }\n}\n","// Login Activity Service — login event history and management\n\nimport type { HttpClient } from \"../http/client\";\nimport type {\n ListLoginEventsRequest,\n ListLoginEventsResponse,\n ReportSuspiciousResponse,\n} from \"../types/login-activity\";\n\nexport class LoginActivityService {\n private readonly httpClient: HttpClient;\n\n constructor(httpClient: HttpClient) {\n this.httpClient = httpClient;\n }\n\n async list(options?: ListLoginEventsRequest): Promise<ListLoginEventsResponse> {\n const params: Record<string, string | number> = {};\n if (options?.limit !== undefined) params.limit = options.limit;\n if (options?.offset !== undefined) params.offset = options.offset;\n if (options?.status !== undefined) params.status = options.status;\n if (options?.dateFrom !== undefined) params.dateFrom = options.dateFrom;\n if (options?.dateTo !== undefined) params.dateTo = options.dateTo;\n\n const { data } = await this.httpClient.get<ListLoginEventsResponse>(\"/auth/login-activity\", {\n params,\n });\n return data;\n }\n\n async markRecognized(eventId: string): Promise<void> {\n await this.httpClient.post(`/auth/login-activity/${eventId}/recognize`);\n }\n\n async reportSuspicious(eventId: string): Promise<ReportSuspiciousResponse> {\n const { data } = await this.httpClient.post<ReportSuspiciousResponse>(\n `/auth/login-activity/${eventId}/report`,\n );\n return data;\n }\n}\n","// Organization Service — organization management\n\nimport type { HttpClient } from \"../http/client\";\nimport type {\n AcceptInvitationRequest,\n CreateOrganizationRequest,\n DeclineInvitationRequest,\n Invitation,\n InviteMemberRequest,\n ListInvitationsRequest,\n ListInvitationsResponse,\n ListMembersRequest,\n ListMembersResponse,\n ListOrganizationsRequest,\n ListOrganizationsResponse,\n Member,\n Organization,\n UpdateMemberRequest,\n UpdateOrganizationRequest,\n} from \"../types/organization\";\n\nexport class OrganizationService {\n private readonly httpClient: HttpClient;\n\n constructor(httpClient: HttpClient) {\n this.httpClient = httpClient;\n }\n\n // --- Organization CRUD ---\n\n async getCurrent(): Promise<Organization> {\n const { data } = await this.httpClient.get<Organization>(\"/organizations/current\");\n return data;\n }\n\n async list(options?: ListOrganizationsRequest): Promise<ListOrganizationsResponse> {\n const params = new URLSearchParams();\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options?.offset !== undefined) params.set(\"offset\", String(options.offset));\n const query = params.toString();\n const path = query ? `/organizations?${query}` : \"/organizations\";\n const { data } = await this.httpClient.get<ListOrganizationsResponse>(path);\n return data;\n }\n\n async create(data: CreateOrganizationRequest): Promise<Organization> {\n const { data: result } = await this.httpClient.post<Organization>(\"/organizations\", data);\n return result;\n }\n\n async update(orgId: string, data: UpdateOrganizationRequest): Promise<Organization> {\n const { data: result } = await this.httpClient.patch<Organization>(\n `/organizations/${orgId}`,\n data,\n );\n return result;\n }\n\n async delete(orgId: string): Promise<void> {\n await this.httpClient.delete(`/organizations/${orgId}`);\n }\n\n // --- Member Management ---\n\n async listMembers(orgId: string, options?: ListMembersRequest): Promise<ListMembersResponse> {\n const params = new URLSearchParams();\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options?.offset !== undefined) params.set(\"offset\", String(options.offset));\n const query = params.toString();\n const path = query\n ? `/organizations/${orgId}/members?${query}`\n : `/organizations/${orgId}/members`;\n const { data } = await this.httpClient.get<ListMembersResponse>(path);\n return data;\n }\n\n async updateMember(orgId: string, userId: string, data: UpdateMemberRequest): Promise<Member> {\n const { data: result } = await this.httpClient.patch<Member>(\n `/organizations/${orgId}/members/${userId}`,\n data,\n );\n return result;\n }\n\n async removeMember(orgId: string, userId: string): Promise<void> {\n await this.httpClient.delete(`/organizations/${orgId}/members/${userId}`);\n }\n\n // --- Invitation Flow ---\n\n async inviteMember(orgId: string, data: InviteMemberRequest): Promise<Invitation> {\n const { data: result } = await this.httpClient.post<Invitation>(\n `/organizations/${orgId}/invitations`,\n data,\n );\n return result;\n }\n\n async acceptInvitation(data: AcceptInvitationRequest): Promise<Organization> {\n const { data: result } = await this.httpClient.post<Organization>(\n \"/organizations/invitations/accept\",\n data,\n );\n return result;\n }\n\n async declineInvitation(data: DeclineInvitationRequest): Promise<void> {\n await this.httpClient.post(\"/organizations/invitations/decline\", data);\n }\n\n // --- Invitation Management ---\n\n async listInvitations(\n orgId: string,\n options?: ListInvitationsRequest,\n ): Promise<ListInvitationsResponse> {\n const params = new URLSearchParams();\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options?.offset !== undefined) params.set(\"offset\", String(options.offset));\n const query = params.toString();\n const path = query\n ? `/organizations/${orgId}/invitations?${query}`\n : `/organizations/${orgId}/invitations`;\n const { data } = await this.httpClient.get<ListInvitationsResponse>(path);\n return data;\n }\n\n async resendInvitation(orgId: string, invitationId: string): Promise<void> {\n await this.httpClient.post(`/organizations/${orgId}/invitations/${invitationId}/resend`);\n }\n\n async cancelInvitation(orgId: string, invitationId: string): Promise<void> {\n await this.httpClient.delete(`/organizations/${orgId}/invitations/${invitationId}`);\n }\n\n // --- Organization Leave ---\n\n async leave(orgId: string): Promise<void> {\n await this.httpClient.post(`/organizations/${orgId}/leave`);\n }\n}\n","// Phone Authentication Service (v2.0)\n\nimport type { HttpClient } from \"../http/client\";\nimport type { LoginResponse } from \"../types/auth\";\nimport type {\n PhoneSignInRequest,\n SendOTPRequest,\n SendOTPResponse,\n VerifyOTPRequest,\n VerifyOTPResponse,\n} from \"../types/phone\";\nimport { validatePhoneNumber } from \"./validators\";\n\nexport class PhoneService {\n private readonly httpClient: HttpClient;\n private readonly storeTokensFn: (accessToken: string, refreshToken: string) => Promise<void>;\n private readonly setLastLoginMethodFn: (method: string) => Promise<void>;\n\n constructor(\n httpClient: HttpClient,\n storeTokens: (accessToken: string, refreshToken: string) => Promise<void>,\n setLastLoginMethod: (method: string) => Promise<void>,\n ) {\n this.httpClient = httpClient;\n this.storeTokensFn = storeTokens;\n this.setLastLoginMethodFn = setLastLoginMethod;\n }\n\n async sendOTP(request: SendOTPRequest): Promise<SendOTPResponse> {\n validatePhoneNumber(request.phoneNumber);\n\n const { data } = await this.httpClient.post<SendOTPResponse>(\"/auth/phone/send-otp\", request, {\n skipAuth: true,\n });\n return data;\n }\n\n async verify(request: VerifyOTPRequest): Promise<VerifyOTPResponse> {\n validatePhoneNumber(request.phoneNumber);\n\n const { data } = await this.httpClient.post<VerifyOTPResponse>(\"/auth/phone/verify\", request, {\n skipAuth: true,\n });\n\n await this.storeTokensFn(data.accessToken, data.refreshToken);\n await this.setLastLoginMethodFn(\"phone\");\n\n return data;\n }\n\n async signIn(request: PhoneSignInRequest): Promise<LoginResponse> {\n validatePhoneNumber(request.phoneNumber);\n\n const { data } = await this.httpClient.post<LoginResponse>(\"/auth/phone/sign-in\", request, {\n skipAuth: true,\n });\n\n await this.storeTokensFn(data.accessToken, data.refreshToken);\n await this.setLastLoginMethodFn(\"phone\");\n\n return data;\n }\n}\n","// Background Token Refresh — automatic token refresh before expiration\n\nexport class BackgroundRefresh {\n private timerId: ReturnType<typeof setTimeout> | null = null;\n private retryTimerId: ReturnType<typeof setTimeout> | null = null;\n\n constructor(\n private readonly refreshFn: () => Promise<{\n accessToken: string;\n expiresIn: number;\n }>,\n private readonly threshold: number,\n private readonly callbacks: {\n onTokenRefreshed?: (token: string) => void;\n onSessionExpired?: () => void;\n } = {},\n ) {}\n\n start(expiresIn: number): void {\n if (typeof setTimeout === \"undefined\") return;\n\n this.stop();\n\n const delayMs = (expiresIn - this.threshold) * 1000;\n\n if (delayMs <= 0) {\n this.executeRefresh();\n return;\n }\n\n this.timerId = setTimeout(() => {\n this.executeRefresh();\n }, delayMs);\n }\n\n stop(): void {\n if (this.timerId !== null) {\n clearTimeout(this.timerId);\n this.timerId = null;\n }\n if (this.retryTimerId !== null) {\n clearTimeout(this.retryTimerId);\n this.retryTimerId = null;\n }\n }\n\n isRunning(): boolean {\n return this.timerId !== null;\n }\n\n private async executeRefresh(): Promise<void> {\n try {\n const result = await this.refreshFn();\n this.callbacks.onTokenRefreshed?.(result.accessToken);\n this.start(result.expiresIn);\n } catch {\n this.timerId = null;\n this.retryTimerId = setTimeout(async () => {\n this.retryTimerId = null;\n try {\n const result = await this.refreshFn();\n this.callbacks.onTokenRefreshed?.(result.accessToken);\n this.start(result.expiresIn);\n } catch {\n this.callbacks.onSessionExpired?.();\n }\n }, 5000);\n }\n }\n}\n","// Session Service — session CRUD, multi-session, device summary\n\nimport type { HttpClient } from \"../http/client\";\nimport type {\n DeviceSession,\n DeviceSummary,\n ListSessionsRequest,\n ListSessionsResponse,\n RevokeAllSessionsOptions,\n RevokeAllSessionsResponse,\n Session,\n SetActiveSessionRequest,\n SetActiveSessionResponse,\n} from \"../types/session\";\n\nexport class SessionService {\n private readonly httpClient: HttpClient;\n private readonly storeTokens: (accessToken: string, refreshToken: string) => Promise<void>;\n\n constructor(\n httpClient: HttpClient,\n storeTokens: (accessToken: string, refreshToken: string) => Promise<void>,\n ) {\n this.httpClient = httpClient;\n this.storeTokens = storeTokens;\n }\n\n // --- Session CRUD ---\n\n async getCurrent(): Promise<Session> {\n const { data } = await this.httpClient.get<Session>(\"/auth/sessions/current\");\n return data;\n }\n\n async list(options?: ListSessionsRequest): Promise<ListSessionsResponse> {\n const params: Record<string, string | number> = {};\n if (options?.limit !== undefined) params.limit = options.limit;\n if (options?.offset !== undefined) params.offset = options.offset;\n\n const { data } = await this.httpClient.get<ListSessionsResponse>(\"/auth/sessions\", { params });\n return data;\n }\n\n async revoke(sessionId: string): Promise<void> {\n await this.httpClient.delete(`/auth/sessions/${sessionId}`);\n }\n\n // --- Revoke All ---\n\n async revokeAll(options?: RevokeAllSessionsOptions): Promise<RevokeAllSessionsResponse> {\n const { data } = await this.httpClient.post<RevokeAllSessionsResponse>(\n \"/auth/sessions/revoke-all\",\n { exceptCurrent: options?.exceptCurrent ?? true },\n );\n return data;\n }\n\n // --- Multi-Session ---\n\n async listDeviceSessions(): Promise<DeviceSession[]> {\n const { data } = await this.httpClient.get<DeviceSession[]>(\"/auth/sessions/device\");\n return data;\n }\n\n async setActive(request: SetActiveSessionRequest): Promise<SetActiveSessionResponse> {\n const { data } = await this.httpClient.post<SetActiveSessionResponse>(\n \"/auth/sessions/set-active\",\n request,\n );\n await this.storeTokens(data.accessToken, data.refreshToken);\n return data;\n }\n\n async revokeDeviceSession(request: {\n sessionToken: string;\n }): Promise<void> {\n await this.httpClient.delete(`/auth/sessions/device/${request.sessionToken}`);\n }\n\n // --- Device Summary ---\n\n async getCurrentDevice(): Promise<DeviceSummary | null> {\n const session = await this.getCurrent();\n return session.device ?? null;\n }\n}\n","// Cookie Storage Adapter — document.cookie wrapper with options\n\nimport type { ITokenStorage } from \"./types\";\n\nexport interface CookieStorageOptions {\n secure?: boolean;\n sameSite?: \"strict\" | \"lax\" | \"none\";\n domain?: string;\n path?: string;\n maxAge?: number;\n}\n\nexport class CookieStorage implements ITokenStorage {\n private readonly secure: boolean;\n private readonly sameSite: \"strict\" | \"lax\" | \"none\";\n private readonly domain?: string;\n private readonly path: string;\n private readonly maxAge?: number;\n\n constructor(options?: CookieStorageOptions) {\n this.secure = options?.secure ?? true;\n this.sameSite = options?.sameSite ?? \"lax\";\n this.domain = options?.domain;\n this.path = options?.path ?? \"/\";\n this.maxAge = options?.maxAge;\n }\n\n async get(key: string): Promise<string | null> {\n if (typeof document === \"undefined\") return null;\n\n const cookies = document.cookie.split(\";\");\n for (const cookie of cookies) {\n const [cookieKey, ...cookieValueParts] = cookie.trim().split(\"=\");\n if (cookieKey === key) {\n const value = cookieValueParts.join(\"=\");\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n }\n }\n return null;\n }\n\n async set(key: string, value: string): Promise<void> {\n if (typeof document === \"undefined\") return;\n\n let cookie = `${key}=${encodeURIComponent(value)}`;\n cookie += `; path=${this.path}`;\n cookie += `; SameSite=${capitalize(this.sameSite)}`;\n\n if (this.secure) {\n cookie += \"; Secure\";\n }\n if (this.domain) {\n cookie += `; Domain=${this.domain}`;\n }\n if (this.maxAge !== undefined) {\n cookie += `; Max-Age=${this.maxAge}`;\n }\n\n document.cookie = cookie;\n }\n\n async remove(key: string): Promise<void> {\n if (typeof document === \"undefined\") return;\n\n let cookie = `${key}=; path=${this.path}; Max-Age=0`;\n if (this.domain) {\n cookie += `; Domain=${this.domain}`;\n }\n document.cookie = cookie;\n }\n}\n\nfunction capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n","// localStorage Adapter — SSR-safe wrapper\n\nimport type { ITokenStorage } from \"./types\";\n\nexport class LocalStorageAdapter implements ITokenStorage {\n async get(key: string): Promise<string | null> {\n if (typeof window === \"undefined\") return null;\n return window.localStorage.getItem(key);\n }\n\n async set(key: string, value: string): Promise<void> {\n if (typeof window === \"undefined\") return;\n window.localStorage.setItem(key, value);\n }\n\n async remove(key: string): Promise<void> {\n if (typeof window === \"undefined\") return;\n window.localStorage.removeItem(key);\n }\n}\n","// In-memory Token Storage — SSR-safe, default implementation\n\nimport type { ITokenStorage } from \"./types\";\n\nexport class MemoryStorage implements ITokenStorage {\n private store = new Map<string, string>();\n\n async get(key: string): Promise<string | null> {\n return this.store.get(key) ?? null;\n }\n\n async set(key: string, value: string): Promise<void> {\n this.store.set(key, value);\n }\n\n async remove(key: string): Promise<void> {\n this.store.delete(key);\n }\n}\n","// Device Types (v2.0)\n\nexport interface Device {\n id: string;\n name: string; // \"Apple iPhone · Safari\"\n deviceType: \"mobile\" | \"desktop\" | \"tablet\";\n browser: string; // \"Chrome 121\"\n os: string; // \"iOS 18\"\n isTrusted: boolean;\n isCurrent: boolean;\n lastUsedAt: string;\n lastIp: string;\n lastCity?: string;\n lastCountry?: string;\n createdAt: string;\n}\n\nexport interface ListDevicesResponse {\n data: Device[];\n total: number;\n}\n\nexport interface RemoveAllOtherDevicesResponse {\n removedCount: number;\n}\n\n// Risk level constants and helpers\n\nexport const RISK_LEVEL_NONE = 0;\nexport const RISK_LEVEL_LOW = 30;\nexport const RISK_LEVEL_MEDIUM = 60;\nexport const RISK_LEVEL_HIGH = 80;\n\nexport type RiskLevel = \"none\" | \"low\" | \"medium\" | \"high\";\n\nexport function getRiskLevel(score: number): RiskLevel {\n if (score >= RISK_LEVEL_HIGH) return \"high\";\n if (score >= RISK_LEVEL_MEDIUM) return \"medium\";\n if (score >= RISK_LEVEL_LOW) return \"low\";\n return \"none\";\n}\n","// AuthClient — main entry point for @atzentis/auth-sdk\n\nimport { BrowserDeviceSignalCollector } from \"./device\";\nimport { HttpClient } from \"./http/client\";\nimport { createAuthInterceptor, createDeviceSignalInterceptor } from \"./http/interceptors\";\nimport { AuthService } from \"./services/auth\";\nimport { DeviceService } from \"./services/device\";\nimport { LoginActivityService } from \"./services/login-activity\";\nimport { OrganizationService } from \"./services/organization\";\nimport { PhoneService } from \"./services/phone\";\nimport { BackgroundRefresh } from \"./services/refresh\";\nimport { SessionService } from \"./services/session\";\nimport { MemoryStorage } from \"./storage\";\nimport type { ITokenStorage } from \"./storage/types\";\nimport type {\n GetOAuthUrlRequest,\n LoginCredentials,\n LoginResponse,\n RefreshTokenResponse,\n RequestPasswordResetRequest,\n ResetPasswordRequest,\n ResetPasswordResponse,\n SendMagicLinkRequest,\n SendVerificationEmailRequest,\n SignupData,\n SignupResponse,\n UsernameLoginCredentials,\n VerifyEmailRequest,\n VerifyEmailResponse,\n VerifyMagicLinkRequest,\n VerifyOAuthCodeRequest,\n} from \"./types/auth\";\nimport type { AuthConfig } from \"./types/config\";\nimport { DEFAULT_REFRESH_TOKEN_STORAGE_KEY, DEFAULT_TOKEN_STORAGE_KEY } from \"./types/config\";\nimport { RISK_LEVEL_LOW } from \"./types/device\";\n\nexport class AuthClient {\n private readonly config: AuthConfig;\n private readonly httpClient: HttpClient;\n private readonly storage: ITokenStorage;\n private readonly authService: AuthService;\n private readonly backgroundRefresh: BackgroundRefresh;\n\n readonly devices: DeviceService;\n readonly loginActivity: LoginActivityService;\n readonly organizations: OrganizationService;\n readonly phone: PhoneService;\n readonly sessions: SessionService;\n\n constructor(config: AuthConfig) {\n this.config = config;\n this.storage = config.storage ?? new MemoryStorage();\n\n const tokenStorageKey = config.tokenStorageKey ?? DEFAULT_TOKEN_STORAGE_KEY;\n const refreshTokenStorageKey = config.tokenStorageKey\n ? `${config.tokenStorageKey}_refresh`\n : DEFAULT_REFRESH_TOKEN_STORAGE_KEY;\n\n this.httpClient = new HttpClient({\n baseUrl: config.baseUrl,\n timeout: config.timeout,\n });\n\n // Add auth interceptor for API key\n const storage = this.storage;\n this.httpClient.addRequestInterceptor(\n createAuthInterceptor({\n tokenProvider: () => null,\n apiKey: config.apiKey,\n }),\n );\n\n // Auth interceptor with async token access\n this.httpClient.addRequestInterceptor(async (request) => {\n if (request.skipAuth) return request;\n const token = await storage.get(tokenStorageKey);\n if (token) {\n return {\n ...request,\n headers: {\n ...request.headers,\n Authorization: `Bearer ${token}`,\n },\n };\n }\n return request;\n });\n\n // Add device signal interceptor if enabled\n if (config.collectDeviceSignals !== false) {\n const collector = new BrowserDeviceSignalCollector();\n this.httpClient.addRequestInterceptor(createDeviceSignalInterceptor(collector));\n }\n\n this.authService = new AuthService(this.httpClient, this.storage, {\n tokenStorageKey,\n refreshTokenStorageKey,\n });\n\n this.devices = new DeviceService(this.httpClient);\n\n this.loginActivity = new LoginActivityService(this.httpClient);\n\n this.organizations = new OrganizationService(this.httpClient);\n\n this.phone = new PhoneService(\n this.httpClient,\n (accessToken, refreshToken) => this.authService.storeTokens(accessToken, refreshToken),\n (method) => this.authService.setLastLoginMethod(method),\n );\n\n this.sessions = new SessionService(this.httpClient, (accessToken, refreshToken) =>\n this.authService.storeTokens(accessToken, refreshToken),\n );\n\n this.backgroundRefresh = new BackgroundRefresh(\n async () => {\n const result = await this.authService.refreshToken();\n return { accessToken: result.accessToken, expiresIn: result.expiresIn };\n },\n config.refreshThreshold ?? 300,\n {\n onTokenRefreshed: config.onTokenRefreshed,\n onSessionExpired: config.onSessionExpired,\n },\n );\n }\n\n // --- Email/Password ---\n\n async login(credentials: LoginCredentials): Promise<LoginResponse> {\n const response = await this.authService.login(credentials);\n this.handleLoginEvent(response);\n this.startRefreshIfEnabled(response.expiresIn);\n return response;\n }\n\n async signup(data: SignupData): Promise<SignupResponse> {\n const response = await this.authService.signup(data);\n this.startRefreshIfEnabled(response.expiresIn);\n return response;\n }\n\n // --- Username ---\n\n async loginWithUsername(credentials: UsernameLoginCredentials): Promise<LoginResponse> {\n const response = await this.authService.loginWithUsername(credentials);\n this.handleLoginEvent(response);\n this.startRefreshIfEnabled(response.expiresIn);\n return response;\n }\n\n async isUsernameAvailable(username: string): Promise<boolean> {\n return this.authService.isUsernameAvailable(username);\n }\n\n // --- OAuth ---\n\n getOAuthUrl(request: GetOAuthUrlRequest): string {\n return this.authService.getOAuthUrl(request);\n }\n\n async verifyOAuthCode(request: VerifyOAuthCodeRequest): Promise<LoginResponse> {\n const response = await this.authService.verifyOAuthCode(request);\n this.handleLoginEvent(response);\n this.startRefreshIfEnabled(response.expiresIn);\n return response;\n }\n\n // --- Magic Link ---\n\n async sendMagicLink(request: SendMagicLinkRequest): Promise<void> {\n return this.authService.sendMagicLink(request);\n }\n\n async verifyMagicLink(request: VerifyMagicLinkRequest): Promise<LoginResponse> {\n const response = await this.authService.verifyMagicLink(request);\n this.handleLoginEvent(response);\n this.startRefreshIfEnabled(response.expiresIn);\n return response;\n }\n\n // --- Email Verification ---\n\n async sendVerificationEmail(request: SendVerificationEmailRequest): Promise<void> {\n return this.authService.sendVerificationEmail(request);\n }\n\n async verifyEmail(request: VerifyEmailRequest): Promise<VerifyEmailResponse> {\n return this.authService.verifyEmail(request);\n }\n\n // --- Password Reset ---\n\n async requestPasswordReset(request: RequestPasswordResetRequest): Promise<void> {\n return this.authService.requestPasswordReset(request);\n }\n\n async resetPassword(request: ResetPasswordRequest): Promise<ResetPasswordResponse> {\n return this.authService.resetPassword(request);\n }\n\n // --- Token Management ---\n\n async getAccessToken(): Promise<string | null> {\n return this.authService.getAccessToken();\n }\n\n async refreshToken(): Promise<RefreshTokenResponse> {\n return this.authService.refreshToken();\n }\n\n async isAuthenticated(): Promise<boolean> {\n return this.authService.isAuthenticated();\n }\n\n async getLastLoginMethod(): Promise<string | null> {\n return this.authService.getLastLoginMethod();\n }\n\n // --- Logout ---\n\n async logout(): Promise<void> {\n this.backgroundRefresh.stop();\n await this.authService.logout();\n this.config.onSessionExpired?.();\n }\n\n async logoutAllDevices(): Promise<void> {\n this.backgroundRefresh.stop();\n await this.authService.logoutAllDevices();\n this.config.onSessionExpired?.();\n }\n\n // --- Private ---\n\n private startRefreshIfEnabled(expiresIn: number): void {\n if (this.config.autoRefreshToken !== false) {\n this.backgroundRefresh.start(expiresIn);\n }\n }\n\n private handleLoginEvent(response: LoginResponse): void {\n if (\n response.loginEvent &&\n response.loginEvent.riskScore >= RISK_LEVEL_LOW &&\n this.config.onNewDeviceAlert\n ) {\n const event = response.loginEvent;\n this.config.onNewDeviceAlert({\n eventId: event.id,\n deviceName: event.deviceName,\n deviceType: event.deviceType,\n city: event.city,\n country: event.country,\n riskScore: event.riskScore,\n method: event.method,\n timestamp: event.createdAt,\n });\n }\n }\n}\n","// Session Types v2.0\n\nimport type { User } from \"./user\";\n\n// --- Session ---\n\nexport interface Session {\n id: string;\n userId: string;\n organizationId: string;\n createdAt: string;\n expiresAt: string;\n ip: string;\n userAgent: string;\n device?: DeviceSummary;\n lastActivityAt?: string;\n}\n\n// --- Device Summary (v2.0) ---\n\nexport interface DeviceSummary {\n id: string;\n name: string;\n deviceType: \"mobile\" | \"desktop\" | \"tablet\";\n isTrusted: boolean;\n}\n\n// --- List Sessions ---\n\nexport interface ListSessionsRequest {\n limit?: number;\n offset?: number;\n}\n\nexport interface ListSessionsResponse {\n data: Session[];\n total: number;\n limit: number;\n offset: number;\n}\n\n// --- Revoke All ---\n\nexport interface RevokeAllSessionsOptions {\n exceptCurrent?: boolean;\n}\n\nexport interface RevokeAllSessionsResponse {\n revokedCount: number;\n}\n\n// --- Multi-Session (v2.0) ---\n\nexport interface DeviceSession {\n sessionToken: string;\n user: User;\n isActive: boolean;\n productId?: string;\n createdAt: string;\n}\n\nexport interface SetActiveSessionRequest {\n sessionToken: string;\n}\n\nexport interface SetActiveSessionResponse {\n accessToken: string;\n refreshToken: string;\n expiresIn: number;\n user: User;\n}\n\n// --- Type Guard ---\n\nexport function hasDevice(session: Session): session is Session & { device: DeviceSummary } {\n return session.device !== undefined;\n}\n","// Auth SDK Error Codes v2.0\n\nexport enum AuthErrorCode {\n // Authentication\n InvalidCredentials = \"INVALID_CREDENTIALS\",\n EmailNotVerified = \"EMAIL_NOT_VERIFIED\",\n TwoFactorRequired = \"TWO_FACTOR_REQUIRED\",\n\n // Phone Auth (v2.0)\n InvalidPhoneNumber = \"INVALID_PHONE_NUMBER\",\n OTPExpired = \"OTP_EXPIRED\",\n OTPInvalid = \"OTP_INVALID\",\n OTPMaxAttempts = \"OTP_MAX_ATTEMPTS\",\n PhoneNumberInUse = \"PHONE_NUMBER_IN_USE\",\n FraudDetected = \"FRAUD_DETECTED\",\n\n // Username (v2.0)\n UsernameTaken = \"USERNAME_TAKEN\",\n UsernameInvalid = \"USERNAME_INVALID\",\n UsernameReserved = \"USERNAME_RESERVED\",\n\n // Device / Login Activity (v2.0)\n DeviceNotFound = \"DEVICE_NOT_FOUND\",\n LoginEventNotFound = \"LOGIN_EVENT_NOT_FOUND\",\n ReauthRequired = \"REAUTH_REQUIRED\",\n\n // Multi-session (v2.0)\n MaxSessionsExceeded = \"MAX_SESSIONS_EXCEEDED\",\n\n // CAPTCHA (v2.0)\n CaptchaRequired = \"CAPTCHA_REQUIRED\",\n CaptchaInvalid = \"CAPTCHA_INVALID\",\n\n // Breach (v2.0)\n PasswordBreached = \"PASSWORD_BREACHED\",\n\n // Session / Token\n SessionExpired = \"SESSION_EXPIRED\",\n TokenExpired = \"TOKEN_EXPIRED\",\n InvalidToken = \"INVALID_TOKEN\",\n\n // Authorization\n UnauthorizedRole = \"UNAUTHORIZED_ROLE\",\n OrganizationNotFound = \"ORGANIZATION_NOT_FOUND\",\n PermissionDenied = \"PERMISSION_DENIED\",\n\n // Rate Limiting & Network\n RateLimited = \"RATE_LIMITED\",\n NetworkError = \"NETWORK_ERROR\",\n Timeout = \"TIMEOUT\",\n\n // User Management\n UserNotFound = \"USER_NOT_FOUND\",\n UserAlreadyExists = \"USER_ALREADY_EXISTS\",\n InvalidEmail = \"INVALID_EMAIL\",\n WeakPassword = \"WEAK_PASSWORD\",\n\n // Organization\n OrganizationLimitExceeded = \"ORG_LIMIT_EXCEEDED\",\n MemberLimitExceeded = \"MEMBER_LIMIT_EXCEEDED\",\n\n // API Keys\n KeyNotFound = \"KEY_NOT_FOUND\",\n KeyRevoked = \"KEY_REVOKED\",\n KeyExpired = \"KEY_EXPIRED\",\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atzentis/auth-sdk",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "description": "Atzentis Auth SDK — zero-dependency TypeScript client for auth.atzentis.com",
5
5
  "keywords": [
6
6
  "atzentis",