@sudoplatform/sudo-user 11.0.0 → 12.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/{lib → cjs/src}/client/apiClient.d.ts +0 -0
  2. package/cjs/src/client/apiClient.js +149 -0
  3. package/cjs/src/client/apiClient.js.map +1 -0
  4. package/{lib → cjs/src}/core/api-key-names.d.ts +0 -0
  5. package/cjs/src/core/api-key-names.js +12 -0
  6. package/cjs/src/core/api-key-names.js.map +1 -0
  7. package/{lib → cjs/src}/core/auth-store.d.ts +0 -0
  8. package/cjs/src/core/auth-store.js +92 -0
  9. package/cjs/src/core/auth-store.js.map +1 -0
  10. package/{lib → cjs/src}/core/crypto.d.ts +0 -0
  11. package/cjs/src/core/crypto.js +3 -0
  12. package/cjs/src/core/crypto.js.map +1 -0
  13. package/{lib → cjs/src}/core/key-manager.d.ts +0 -0
  14. package/cjs/src/core/key-manager.js +113 -0
  15. package/cjs/src/core/key-manager.js.map +1 -0
  16. package/cjs/src/core/protected-store.d.ts +5 -0
  17. package/cjs/src/core/protected-store.js +3 -0
  18. package/cjs/src/core/protected-store.js.map +1 -0
  19. package/{lib → cjs/src}/core/publisher.d.ts +0 -0
  20. package/cjs/src/core/publisher.js +3 -0
  21. package/cjs/src/core/publisher.js.map +1 -0
  22. package/{lib → cjs/src}/core/sdk-config.d.ts +0 -0
  23. package/cjs/src/core/sdk-config.js +61 -0
  24. package/cjs/src/core/sdk-config.js.map +1 -0
  25. package/{lib → cjs/src}/core/subscriber.d.ts +0 -0
  26. package/cjs/src/core/subscriber.js +3 -0
  27. package/cjs/src/core/subscriber.js.map +1 -0
  28. package/{lib → cjs/src}/gen/graphql-types.d.ts +0 -0
  29. package/cjs/src/gen/graphql-types.js +105 -0
  30. package/cjs/src/gen/graphql-types.js.map +1 -0
  31. package/{lib → cjs/src}/index.d.ts +0 -0
  32. package/cjs/src/index.js +13 -0
  33. package/cjs/src/index.js.map +1 -0
  34. package/{lib/runtimes/node/node-crypto.d.ts → cjs/src/runtimes/browser/browser-crypto.d.ts} +0 -0
  35. package/cjs/src/runtimes/browser/browser-crypto.js +10 -0
  36. package/cjs/src/runtimes/browser/browser-crypto.js.map +1 -0
  37. package/cjs/src/runtimes/node/node-crypto.d.ts +2 -0
  38. package/cjs/src/runtimes/node/node-crypto.js +9 -0
  39. package/cjs/src/runtimes/node/node-crypto.js.map +1 -0
  40. package/{lib → cjs/src}/sdk.d.ts +0 -0
  41. package/cjs/src/sdk.js +9 -0
  42. package/cjs/src/sdk.js.map +1 -0
  43. package/{lib → cjs/src}/user/auth-provider.d.ts +0 -0
  44. package/cjs/src/user/auth-provider.js +116 -0
  45. package/cjs/src/user/auth-provider.js.map +1 -0
  46. package/{lib → cjs/src}/user/auth.d.ts +0 -0
  47. package/cjs/src/user/auth.js +136 -0
  48. package/cjs/src/user/auth.js.map +1 -0
  49. package/{lib → cjs/src}/user/error.d.ts +0 -0
  50. package/{lib → cjs/src}/user/error.js +16 -29
  51. package/cjs/src/user/error.js.map +1 -0
  52. package/{lib → cjs/src}/user/identity-provider.d.ts +0 -0
  53. package/cjs/src/user/identity-provider.js +245 -0
  54. package/cjs/src/user/identity-provider.js.map +1 -0
  55. package/{lib → cjs/src}/user/user-client-interface.d.ts +0 -0
  56. package/cjs/src/user/user-client-interface.js +3 -0
  57. package/cjs/src/user/user-client-interface.js.map +1 -0
  58. package/{lib → cjs/src}/user/user-client.d.ts +0 -0
  59. package/cjs/src/user/user-client.js +440 -0
  60. package/cjs/src/user/user-client.js.map +1 -0
  61. package/{lib → cjs/src}/user/user-key-names.d.ts +0 -0
  62. package/cjs/src/user/user-key-names.js +10 -0
  63. package/cjs/src/user/user-key-names.js.map +1 -0
  64. package/{lib → cjs/src}/utils/resolvable-promise.d.ts +0 -0
  65. package/cjs/src/utils/resolvable-promise.js +20 -0
  66. package/cjs/src/utils/resolvable-promise.js.map +1 -0
  67. package/cjs/test/integration/user-client-int.spec.d.ts +1 -0
  68. package/cjs/test/integration/user-client-int.spec.js +206 -0
  69. package/cjs/test/integration/user-client-int.spec.js.map +1 -0
  70. package/cjs/test/unit/core/sdk-config.spec.d.ts +1 -0
  71. package/cjs/test/unit/core/sdk-config.spec.js +51 -0
  72. package/cjs/test/unit/core/sdk-config.spec.js.map +1 -0
  73. package/cjs/test/unit/key-manager.spec.d.ts +1 -0
  74. package/cjs/test/unit/key-manager.spec.js +23 -0
  75. package/cjs/test/unit/key-manager.spec.js.map +1 -0
  76. package/cjs/test/unit/user-client.spec.d.ts +1 -0
  77. package/cjs/test/unit/user-client.spec.js +323 -0
  78. package/cjs/test/unit/user-client.spec.js.map +1 -0
  79. package/docs/classes/AlreadyRegisteredError.html +4 -4
  80. package/docs/classes/IdentityServiceConfigNotFoundError.html +4 -4
  81. package/lib/src/client/apiClient.d.ts +25 -0
  82. package/lib/src/client/apiClient.js +145 -0
  83. package/lib/src/client/apiClient.js.map +1 -0
  84. package/lib/src/core/api-key-names.d.ts +8 -0
  85. package/lib/src/core/api-key-names.js +9 -0
  86. package/lib/src/core/api-key-names.js.map +1 -0
  87. package/lib/src/core/auth-store.d.ts +51 -0
  88. package/lib/src/core/auth-store.js +88 -0
  89. package/lib/src/core/auth-store.js.map +1 -0
  90. package/lib/src/core/crypto.d.ts +3 -0
  91. package/lib/src/core/crypto.js +2 -0
  92. package/lib/src/core/crypto.js.map +1 -0
  93. package/lib/src/core/key-manager.d.ts +31 -0
  94. package/lib/src/core/key-manager.js +108 -0
  95. package/lib/src/core/key-manager.js.map +1 -0
  96. package/lib/src/core/protected-store.d.ts +5 -0
  97. package/lib/src/core/protected-store.js +2 -0
  98. package/lib/src/core/protected-store.js.map +1 -0
  99. package/lib/src/core/publisher.d.ts +6 -0
  100. package/lib/src/core/publisher.js +2 -0
  101. package/lib/src/core/publisher.js.map +1 -0
  102. package/lib/src/core/sdk-config.d.ts +52 -0
  103. package/lib/src/core/sdk-config.js +56 -0
  104. package/lib/src/core/sdk-config.js.map +1 -0
  105. package/lib/src/core/subscriber.d.ts +3 -0
  106. package/lib/src/core/subscriber.js +2 -0
  107. package/lib/src/core/subscriber.js.map +1 -0
  108. package/lib/src/gen/graphql-types.d.ts +101 -0
  109. package/lib/src/gen/graphql-types.js +102 -0
  110. package/lib/src/gen/graphql-types.js.map +1 -0
  111. package/lib/src/index.d.ts +4 -0
  112. package/lib/src/index.js +6 -0
  113. package/lib/src/index.js.map +1 -0
  114. package/lib/src/runtimes/browser/browser-crypto.d.ts +2 -0
  115. package/lib/src/runtimes/browser/browser-crypto.js +7 -0
  116. package/lib/src/runtimes/browser/browser-crypto.js.map +1 -0
  117. package/lib/src/runtimes/node/node-crypto.d.ts +2 -0
  118. package/lib/src/runtimes/node/node-crypto.js +6 -0
  119. package/lib/src/runtimes/node/node-crypto.js.map +1 -0
  120. package/lib/src/sdk.d.ts +1 -0
  121. package/lib/src/sdk.js +6 -0
  122. package/lib/src/sdk.js.map +1 -0
  123. package/lib/src/user/auth-provider.d.ts +97 -0
  124. package/lib/src/user/auth-provider.js +108 -0
  125. package/lib/src/user/auth-provider.js.map +1 -0
  126. package/lib/src/user/auth.d.ts +64 -0
  127. package/lib/src/user/auth.js +131 -0
  128. package/lib/src/user/auth.js.map +1 -0
  129. package/lib/src/user/error.d.ts +18 -0
  130. package/lib/src/user/error.js +28 -0
  131. package/lib/src/user/error.js.map +1 -0
  132. package/lib/src/user/identity-provider.d.ts +73 -0
  133. package/lib/src/user/identity-provider.js +241 -0
  134. package/lib/src/user/identity-provider.js.map +1 -0
  135. package/lib/src/user/user-client-interface.d.ts +168 -0
  136. package/lib/src/user/user-client-interface.js +2 -0
  137. package/lib/src/user/user-client-interface.js.map +1 -0
  138. package/lib/src/user/user-client.d.ts +82 -0
  139. package/lib/src/user/user-client.js +435 -0
  140. package/lib/src/user/user-client.js.map +1 -0
  141. package/lib/src/user/user-key-names.d.ts +6 -0
  142. package/lib/src/user/user-key-names.js +7 -0
  143. package/lib/src/user/user-key-names.js.map +1 -0
  144. package/lib/src/utils/resolvable-promise.d.ts +9 -0
  145. package/lib/src/utils/resolvable-promise.js +16 -0
  146. package/lib/src/utils/resolvable-promise.js.map +1 -0
  147. package/lib/test/integration/user-client-int.spec.d.ts +1 -0
  148. package/lib/test/integration/user-client-int.spec.js +203 -0
  149. package/lib/test/integration/user-client-int.spec.js.map +1 -0
  150. package/lib/test/unit/core/sdk-config.spec.d.ts +1 -0
  151. package/lib/test/unit/core/sdk-config.spec.js +49 -0
  152. package/lib/test/unit/core/sdk-config.spec.js.map +1 -0
  153. package/lib/test/unit/key-manager.spec.d.ts +1 -0
  154. package/lib/test/unit/key-manager.spec.js +21 -0
  155. package/lib/test/unit/key-manager.spec.js.map +1 -0
  156. package/lib/test/unit/user-client.spec.d.ts +1 -0
  157. package/lib/test/unit/user-client.spec.js +320 -0
  158. package/lib/test/unit/user-client.spec.js.map +1 -0
  159. package/package.json +23 -22
  160. package/lib/client/apiClient.js +0 -190
  161. package/lib/core/api-key-names.js +0 -15
  162. package/lib/core/auth-store.js +0 -144
  163. package/lib/core/crypto.js +0 -5
  164. package/lib/core/key-manager.js +0 -158
  165. package/lib/core/protected-store.js +0 -5
  166. package/lib/core/publisher.js +0 -5
  167. package/lib/core/sdk-config.js +0 -56
  168. package/lib/core/subscriber.js +0 -5
  169. package/lib/gen/graphql-types.js +0 -141
  170. package/lib/index.js +0 -67
  171. package/lib/runtimes/browser/browser-crypto.js +0 -15
  172. package/lib/runtimes/node/node-crypto.js +0 -12
  173. package/lib/sdk.js +0 -18
  174. package/lib/user/auth-provider.js +0 -158
  175. package/lib/user/auth.js +0 -183
  176. package/lib/user/identity-provider.js +0 -270
  177. package/lib/user/user-client-interface.js +0 -5
  178. package/lib/user/user-client.js +0 -522
  179. package/lib/user/user-key-names.js +0 -13
  180. package/lib/utils/resolvable-promise.js +0 -22
@@ -0,0 +1,168 @@
1
+ import { SudoKeyManager } from '@sudoplatform/sudo-common';
2
+ import { AuthenticationProvider } from './auth-provider';
3
+ /**
4
+ * Encapsulates the authentication tokens obtained from a successful authentication.
5
+ *
6
+ * @param idToken ID token containing the user's identity attributes.
7
+ * @param accessToken access token required for authorizing API access.
8
+ * @param refreshToken refresh token used for refreshing ID and access tokens.
9
+ * @param tokenExpiry expiry of ID and access tokens in milliseconds.
10
+ */
11
+ export interface AuthenticationTokens {
12
+ idToken: string;
13
+ accessToken: string;
14
+ refreshToken: string;
15
+ tokenExpiry: number;
16
+ }
17
+ /**
18
+ * Interface encapsulating a library of functions for calling Sudo Platform identity service,
19
+ * handling federated sign in, managing keys and performing cryptographic operations.
20
+ */
21
+ export interface SudoUserClient {
22
+ /**
23
+ * Presents the sign in UI for federated sign in using an external identity provider.
24
+ */
25
+ presentFederatedSignInUI(): void;
26
+ /**
27
+ * Processes tokens from federated sign in returned to the specified URL.
28
+ * The tokens are passed to the web app via a redirect URL.
29
+ *
30
+ * @param url callback URL containing the tokens.
31
+ * @return Successful authentication result AuthenticationTokens.
32
+ */
33
+ processFederatedSignInTokens(url: string): Promise<AuthenticationTokens>;
34
+ /**
35
+ * Returns the ID token cached from the last sign-in.
36
+ *
37
+ * @return ID token.
38
+ */
39
+ getIdToken(): Promise<string | undefined>;
40
+ /**
41
+ * Returns the access token cached from the last sign-in.
42
+ *
43
+ * @return access token.
44
+ */
45
+ getAccessToken(): Promise<string | undefined>;
46
+ /**
47
+ * Returns the refresh token cached from the last sign-in.
48
+ *
49
+ * @return refresh token.
50
+ */
51
+ getRefreshToken(): Promise<string | undefined>;
52
+ /**
53
+ * Returns the ID and access token expiry cached from the last sign-in.
54
+ *
55
+ * @return token expiry.
56
+ */
57
+ getTokenExpiry(): Promise<Date | undefined>;
58
+ /**
59
+ * Returns the refresh token expiry cached from the last sign-in.
60
+ *
61
+ * @return refresh token expiry.
62
+ */
63
+ getRefreshTokenExpiry(): Promise<Date | undefined>;
64
+ /**
65
+ * Indicates whether or not this client is signed in with Sudo Platform backend. The client is
66
+ * considered signed in if it cached valid ID, access and refresh tokens.
67
+ *
68
+ * @return *true* if the client is signed in.
69
+ */
70
+ isSignedIn(): Promise<boolean>;
71
+ /**
72
+ * Refresh the access and ID tokens using the refresh token.
73
+ *
74
+ * @param refreshToken refresh token used to refresh the access and ID tokens.
75
+ * @return Successful authentication result AuthenticationTokens containing refreshed tokens
76
+ */
77
+ refreshTokens(refreshToken: string): Promise<AuthenticationTokens>;
78
+ /**
79
+ * Retrieves the latest ID token. This is to be used by the AWS AppSync client.
80
+ *
81
+ * @returns the latest ID token
82
+ */
83
+ getLatestAuthToken(): Promise<string>;
84
+ /**
85
+ * Returns the user name associated with this client. The username maybe needed to contact
86
+ * the support team when diagnosing an issue related to a specific user.
87
+ *
88
+ * @return user name.
89
+ */
90
+ getUserName(): Promise<string | undefined>;
91
+ /**
92
+ * Sets the user name associated with this client.
93
+ *
94
+ * @param name user name.
95
+ */
96
+ setUserName(name: string): Promise<void>;
97
+ /**
98
+ * Returns the subject of the user associated with this client.
99
+ * Note: This is an internal method used by other Sudo platform SDKs.
100
+ *
101
+ * @return user subject.
102
+ */
103
+ getSubject(): Promise<string | undefined>;
104
+ /**
105
+ * Returns the specified claim associated with the user's identity.
106
+ *
107
+ * @param name claim name.
108
+ */
109
+ getUserClaim(name: string): Promise<any | undefined>;
110
+ /**
111
+ * Signs out the user from this device.
112
+ */
113
+ signOut(): Promise<void>;
114
+ /**
115
+ * Signs out the user from all devices.
116
+ */
117
+ globalSignOut(): Promise<void>;
118
+ /**
119
+ * Registers this client against the backend with an external authentication provider. The caller must
120
+ * implement AuthenticationProvider protocol to return the appropriate authentication token required
121
+ * to authorize the registration request.
122
+ *
123
+ * @param authenticationProvider authentication provider that provides the authentication token.
124
+ * @param registrationId registration ID to uniquely identify this registration request.
125
+ * @return user ID of the newly created user
126
+ */
127
+ registerWithAuthenticationProvider(authenticationProvider: AuthenticationProvider, registrationId?: string): Promise<string>;
128
+ /**
129
+ * Sign into the backend using an external authentication provider. Caller must implement
130
+ * *AuthenticationProvider* interface to return the appropriate authentication token associated with
131
+ * the external identity registered with *registerWithAuthenticationProvider*.
132
+ *
133
+ * @param authenticationProvider authentication provider that provides the authentication token.
134
+ * @return authentication tokens associated with the successful sign in.
135
+ */
136
+ signInWithAuthenticationProvider(authenticationProvider: AuthenticationProvider): Promise<AuthenticationTokens>;
137
+ /**
138
+ * Indicates whether or not this client is registered with Sudo Platform backend.
139
+ *
140
+ * @return *true* if the client is registered.
141
+ */
142
+ isRegistered(): Promise<boolean>;
143
+ /**
144
+ * Sign into the backend using a private key. The client must have created a private/public key pair via
145
+ * the *registerWithAuthenticationProvider* method.
146
+ *
147
+ * @return authentication tokens associated with the successful sign in.
148
+ */
149
+ signInWithKey(): Promise<AuthenticationTokens>;
150
+ /**
151
+ * Clears cached authentication tokens.
152
+ */
153
+ clearAuthenticationTokens(): Promise<void>;
154
+ /**
155
+ * Presents the Cognito hosted UI signout endpoint.
156
+ * When the endpoint is invoked, the hosted web app's cookies
157
+ * will be invalidated, but the user is not logged out of Cognito.
158
+ */
159
+ presentSignOutUI(): void;
160
+ /**
161
+ * Resets internal state and clears any cached data.
162
+ */
163
+ reset(): void;
164
+ /**
165
+ * Getter to retrieve the SudoKeyManager
166
+ */
167
+ readonly sudoKeyManager: SudoKeyManager;
168
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=user-client-interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-client-interface.js","sourceRoot":"","sources":["../../../src/user/user-client-interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,82 @@
1
+ import { Logger, SudoKeyManager } from '@sudoplatform/sudo-common';
2
+ import { AuthenticationProvider } from '..';
3
+ import { ApiClient } from '../client/apiClient';
4
+ import { AuthenticationStore } from '../core/auth-store';
5
+ import { Config } from '../core/sdk-config';
6
+ import { AuthUI } from './auth';
7
+ import { IdentityProvider } from './identity-provider';
8
+ import { AuthenticationTokens, SudoUserClient } from './user-client-interface';
9
+ export interface SudoUserOptions {
10
+ authenticationStore?: AuthenticationStore;
11
+ sudoKeyManager?: SudoKeyManager;
12
+ apiClient?: ApiClient;
13
+ authUI?: AuthUI;
14
+ identityProvider?: IdentityProvider;
15
+ launchUriFn?: (url: string) => void;
16
+ config?: Config;
17
+ logger?: Logger;
18
+ }
19
+ export declare class DefaultSudoUserClient implements SudoUserClient {
20
+ private config;
21
+ private keyManager;
22
+ private sudoUserKeyManager;
23
+ private authenticationStore;
24
+ private identityProvider;
25
+ private apiClient;
26
+ private logger;
27
+ private authUI?;
28
+ private launchUriFn?;
29
+ constructor(options?: SudoUserOptions);
30
+ get sudoKeyManager(): SudoKeyManager;
31
+ presentFederatedSignInUI(): void;
32
+ processFederatedSignInTokens(url: string): Promise<AuthenticationTokens>;
33
+ getIdToken(): Promise<string | undefined>;
34
+ getAccessToken(): Promise<string | undefined>;
35
+ getRefreshToken(): Promise<string | undefined>;
36
+ getTokenExpiry(): Promise<Date | undefined>;
37
+ getRefreshTokenExpiry(): Promise<Date | undefined>;
38
+ getUserName(): Promise<string | undefined>;
39
+ setUserName(name: string): Promise<void>;
40
+ getUserClaim(name: string): Promise<any | undefined>;
41
+ getSubject(): Promise<string | undefined>;
42
+ isSignedIn(): Promise<boolean>;
43
+ refreshTokens(refreshToken: string): Promise<AuthenticationTokens>;
44
+ getLatestAuthToken(): Promise<string>;
45
+ signOut(): Promise<void>;
46
+ globalSignOut(): Promise<void>;
47
+ registerWithAuthenticationProvider(authenticationProvider: AuthenticationProvider, registrationId?: string): Promise<string>;
48
+ signInWithAuthenticationProvider(authenticationProvider: AuthenticationProvider): Promise<AuthenticationTokens>;
49
+ isRegistered(): Promise<boolean>;
50
+ signInWithKey(): Promise<AuthenticationTokens>;
51
+ deregister(): Promise<void>;
52
+ clearAuthenticationTokens(): Promise<void>;
53
+ presentSignOutUI(): void;
54
+ reset(): void;
55
+ private getTokenClaim;
56
+ /**
57
+ * Store the authentication tokens and user id of the signed in user. This function
58
+ * is only called when a user has successfully signed in using a private key.
59
+ */
60
+ private storeTokens;
61
+ private registerFederatedIdAndRefreshTokens;
62
+ private generateRegistrationData;
63
+ private getAuthTokens;
64
+ /**
65
+ * Provide a custom auth UI. This is mainly used for unit testing (optional).
66
+ */
67
+ setAuthUI(authUI: AuthUI): void;
68
+ /**
69
+ * Provide a custom identity provider. This is mainly used for unit testing (optional).
70
+ */
71
+ setIdentityProvider(identityProvider: IdentityProvider): void;
72
+ /**
73
+ * Provide a custom function to open the sign in url.
74
+ * This is mainly used for unit testing (optional).
75
+ */
76
+ setLaunchUriFn(launchUriFn: (url: string) => void): void;
77
+ /**
78
+ * Provide a custom authentication store.
79
+ * This is mainly used for unit testing (optional).
80
+ */
81
+ setAuthenticationStore(authenticationStore: AuthenticationStore): void;
82
+ }
@@ -0,0 +1,435 @@
1
+ import { AuthenticationError, DefaultLogger, DefaultSudoKeyManager, FatalError, KeyNotFoundError, NotAuthorizedError, NotRegisteredError, NotSignedInError, PublicKeyFormat, RegisterError, } from '@sudoplatform/sudo-common';
2
+ import { WebSudoCryptoProvider } from '@sudoplatform/sudo-web-crypto-provider';
3
+ import * as JWT from 'jsonwebtoken';
4
+ import { v4 } from 'uuid';
5
+ import { ApiClient } from '../client/apiClient';
6
+ import { apiKeyNames } from '../core/api-key-names';
7
+ import { AuthenticationStore } from '../core/auth-store';
8
+ import { KeyManager } from '../core/key-manager';
9
+ import { getIdentityServiceConfig } from '../core/sdk-config';
10
+ import { CognitoAuthUI } from './auth';
11
+ import { AlreadyRegisteredError } from './error';
12
+ import { CognitoUserPoolIdentityProvider, } from './identity-provider';
13
+ import { userKeyNames } from './user-key-names';
14
+ export class DefaultSudoUserClient {
15
+ constructor(options) {
16
+ this.logger = options?.logger ?? new DefaultLogger('SudoUser', 'warn');
17
+ this.config = options?.config ?? getIdentityServiceConfig();
18
+ this.authenticationStore =
19
+ options?.authenticationStore ?? new AuthenticationStore();
20
+ if (options?.sudoKeyManager) {
21
+ this.sudoUserKeyManager = options?.sudoKeyManager;
22
+ }
23
+ else {
24
+ const cryptoProvider = new WebSudoCryptoProvider('SudoUserClient', 'com.sudoplatform.appservicename');
25
+ this.sudoUserKeyManager = new DefaultSudoKeyManager(cryptoProvider);
26
+ }
27
+ this.keyManager = new KeyManager(this.sudoUserKeyManager);
28
+ this.launchUriFn = options?.launchUriFn;
29
+ this.identityProvider =
30
+ options?.identityProvider ??
31
+ new CognitoUserPoolIdentityProvider(this.keyManager, this.config, this.logger);
32
+ const federatedSignInConfig = this.config?.federatedSignIn;
33
+ if (federatedSignInConfig) {
34
+ this.authUI =
35
+ options?.authUI ??
36
+ new CognitoAuthUI(this.authenticationStore, federatedSignInConfig, this.keyManager, this.logger, this.launchUriFn);
37
+ }
38
+ this.apiClient =
39
+ options?.apiClient ??
40
+ new ApiClient(this.config.identityService.region, this.config.identityService.apiUrl, this, this.logger);
41
+ }
42
+ get sudoKeyManager() {
43
+ return this.sudoUserKeyManager;
44
+ }
45
+ presentFederatedSignInUI() {
46
+ try {
47
+ this.authUI?.presentFederatedSignInUI();
48
+ }
49
+ catch (err) {
50
+ const error = err;
51
+ this.logger.error('Failed to launch the federated sign in UI.', { error });
52
+ throw new AuthenticationError(error.message);
53
+ }
54
+ }
55
+ async processFederatedSignInTokens(url) {
56
+ try {
57
+ let authTokens = await this.authUI?.processFederatedSignInTokens(url);
58
+ if (authTokens) {
59
+ authTokens = await this.registerFederatedIdAndRefreshTokens(authTokens);
60
+ return authTokens;
61
+ }
62
+ else {
63
+ throw new AuthenticationError('Authentication tokens missing.');
64
+ }
65
+ }
66
+ catch (err) {
67
+ const error = err;
68
+ this.logger.error('Failed to process the federated sign in redirect.', {
69
+ error,
70
+ });
71
+ throw new AuthenticationError(error.message);
72
+ }
73
+ }
74
+ async getIdToken() {
75
+ return await this.keyManager.getString(apiKeyNames.idToken);
76
+ }
77
+ async getAccessToken() {
78
+ return await this.keyManager.getString(apiKeyNames.accessToken);
79
+ }
80
+ async getRefreshToken() {
81
+ return await this.keyManager.getString(apiKeyNames.refreshToken);
82
+ }
83
+ async getTokenExpiry() {
84
+ const expiry = await this.keyManager.getString(apiKeyNames.tokenExpiry);
85
+ return expiry ? new Date(Number(expiry) * 1000) : undefined;
86
+ }
87
+ async getRefreshTokenExpiry() {
88
+ let expiry = undefined;
89
+ const timeSinceEpoch = await this.keyManager.getString(apiKeyNames.refreshTokenExpiry);
90
+ if (timeSinceEpoch) {
91
+ expiry = new Date(Number(timeSinceEpoch));
92
+ }
93
+ return expiry;
94
+ }
95
+ async getUserName() {
96
+ try {
97
+ return await this.keyManager.getString(userKeyNames.userId);
98
+ }
99
+ catch {
100
+ return undefined;
101
+ }
102
+ }
103
+ async setUserName(name) {
104
+ await this.keyManager.removeItem(userKeyNames.userId);
105
+ await this.keyManager.addString(userKeyNames.userId, name);
106
+ }
107
+ async getUserClaim(name) {
108
+ const idToken = await this.getIdToken();
109
+ if (!idToken)
110
+ return undefined;
111
+ return this.getTokenClaim(idToken, name);
112
+ }
113
+ async getSubject() {
114
+ return await this.getUserClaim('sub');
115
+ }
116
+ async isSignedIn() {
117
+ try {
118
+ const authTokens = await this.getAuthTokens();
119
+ const expiry = await this.getRefreshTokenExpiry();
120
+ if (authTokens &&
121
+ authTokens.idToken &&
122
+ authTokens.accessToken &&
123
+ authTokens.refreshToken &&
124
+ expiry &&
125
+ // Considered signed in up to 1 hour before the expiry of refresh token.
126
+ expiry.getTime() > new Date().getTime() + 60 * 60 * 1000) {
127
+ return true;
128
+ }
129
+ else {
130
+ return false;
131
+ }
132
+ }
133
+ catch (err) {
134
+ // The key manager throws a KeyNotFoundError if an item is not found
135
+ // in which case we want to indicate that the user is not signed in.
136
+ return false;
137
+ }
138
+ }
139
+ async refreshTokens(refreshToken) {
140
+ try {
141
+ const uid = await this.getUserName();
142
+ if (uid) {
143
+ const authTokens = await this.identityProvider.refreshTokens(refreshToken);
144
+ await this.storeTokens(uid, authTokens);
145
+ return authTokens;
146
+ }
147
+ else {
148
+ throw new NotRegisteredError('Not registered.');
149
+ }
150
+ }
151
+ catch (err) {
152
+ const error = err;
153
+ throw new AuthenticationError(error.message);
154
+ }
155
+ }
156
+ async getLatestAuthToken() {
157
+ try {
158
+ const idToken = await this.getIdToken();
159
+ const refreshToken = await this.getRefreshToken();
160
+ const expiry = await this.getTokenExpiry();
161
+ if (idToken && refreshToken && expiry) {
162
+ if (expiry.getTime() > new Date().getTime() + 600 * 1000) {
163
+ return idToken;
164
+ }
165
+ else {
166
+ try {
167
+ const authTokens = await this.refreshTokens(refreshToken);
168
+ return authTokens.idToken;
169
+ }
170
+ catch (error) {
171
+ this.logger.info('getLatestAuthToken: Token refresh failed', {
172
+ error,
173
+ });
174
+ // return an empty id token
175
+ return '';
176
+ }
177
+ }
178
+ }
179
+ else {
180
+ // If tokens are missing then it's likely due to the client not being signed in.
181
+ // Return an empty id token.
182
+ return '';
183
+ }
184
+ }
185
+ catch (err) {
186
+ // The key manager throws a KeyNotFoundError if an item is not found
187
+ // which would indicate that the client is likely not signed in.
188
+ // Return an empty id token.
189
+ return '';
190
+ }
191
+ }
192
+ async signOut() {
193
+ let refreshToken;
194
+ try {
195
+ refreshToken = await this.getRefreshToken();
196
+ }
197
+ catch (err) {
198
+ if (err instanceof KeyNotFoundError) {
199
+ throw new NotSignedInError();
200
+ }
201
+ else {
202
+ throw err;
203
+ }
204
+ }
205
+ if (refreshToken) {
206
+ await this.identityProvider.signOut(refreshToken);
207
+ }
208
+ else {
209
+ throw new NotSignedInError();
210
+ }
211
+ }
212
+ async globalSignOut() {
213
+ if (!(await this.isSignedIn())) {
214
+ throw new NotSignedInError();
215
+ }
216
+ await this.apiClient.globalSignOut();
217
+ this.clearAuthenticationTokens();
218
+ }
219
+ async registerWithAuthenticationProvider(authenticationProvider, registrationId) {
220
+ this.logger.info('Registering using an external authentication provider.');
221
+ if (!(await this.isRegistered())) {
222
+ const authInfo = await authenticationProvider.getAuthenticationInfo();
223
+ if (!authInfo.isValid()) {
224
+ throw new NotAuthorizedError('Authentication provider returned invalid authentication info.');
225
+ }
226
+ const token = authInfo.encode();
227
+ const jwt = JWT.decode(token, { complete: true });
228
+ let uid;
229
+ if (jwt && jwt.payload['sub']) {
230
+ uid = jwt.payload['sub'];
231
+ }
232
+ else {
233
+ uid = v4();
234
+ }
235
+ const publicKey = await this.generateRegistrationData();
236
+ const data = {
237
+ challengeType: authInfo.type,
238
+ answer: token,
239
+ registrationId: registrationId ? registrationId : v4(),
240
+ publicKey: JSON.stringify(publicKeyToRSAPublicKey(publicKey)),
241
+ };
242
+ const validationData = Object.keys(data).map((key) => {
243
+ return {
244
+ Name: key,
245
+ Value: data[key],
246
+ };
247
+ });
248
+ const userId = await this.identityProvider.register(uid, validationData);
249
+ if (userId) {
250
+ await this.setUserName(userId);
251
+ return userId;
252
+ }
253
+ else {
254
+ throw new RegisterError('Registration was successful but not user ID was returned.');
255
+ }
256
+ }
257
+ else {
258
+ throw new AlreadyRegisteredError();
259
+ }
260
+ }
261
+ async signInWithAuthenticationProvider(authenticationProvider) {
262
+ this.logger.info('Signing in using external authentication provider.');
263
+ const authInfo = await authenticationProvider.getAuthenticationInfo();
264
+ if (!authInfo.isValid()) {
265
+ throw new NotAuthorizedError('Authentication provider returned invalid authentication info.');
266
+ }
267
+ const uid = authInfo.getUsername();
268
+ const token = authInfo.encode();
269
+ const type = authInfo.type;
270
+ let authTokens = await this.identityProvider.signInWithToken(uid, token, type);
271
+ await this.storeTokens(uid, authTokens);
272
+ authTokens = await this.registerFederatedIdAndRefreshTokens(authTokens);
273
+ return authTokens;
274
+ }
275
+ async isRegistered() {
276
+ try {
277
+ const uid = await this.getUserName();
278
+ return uid ? true : false;
279
+ }
280
+ catch (err) {
281
+ return false;
282
+ }
283
+ }
284
+ async signInWithKey() {
285
+ this.logger.info('Signing in using private key.');
286
+ const uid = await this.getUserName();
287
+ const userKeyId = await this.keyManager.getString('userKeyId');
288
+ if (uid && userKeyId) {
289
+ let authTokens = await this.identityProvider.signInWithKey(uid, userKeyId);
290
+ if (authTokens) {
291
+ await this.storeTokens(uid, authTokens);
292
+ authTokens = await this.registerFederatedIdAndRefreshTokens(authTokens);
293
+ return authTokens;
294
+ }
295
+ else {
296
+ throw new FatalError('Unexpected error. Unable to sign in.');
297
+ }
298
+ }
299
+ else {
300
+ throw new NotRegisteredError('Not registered.');
301
+ }
302
+ }
303
+ async deregister() {
304
+ await this.apiClient.deregister();
305
+ await this.keyManager.reset();
306
+ this.clearAuthenticationTokens();
307
+ }
308
+ async clearAuthenticationTokens() {
309
+ await this.keyManager.removeItem(apiKeyNames.idToken);
310
+ await this.keyManager.removeItem(apiKeyNames.accessToken);
311
+ await this.keyManager.removeItem(apiKeyNames.refreshToken);
312
+ await this.keyManager.removeItem(apiKeyNames.tokenExpiry);
313
+ this.authenticationStore.reset();
314
+ if (this.authUI) {
315
+ this.authUI.reset();
316
+ }
317
+ }
318
+ presentSignOutUI() {
319
+ this.authUI?.presentSignOutUI();
320
+ }
321
+ reset() {
322
+ this.keyManager.reset();
323
+ this.apiClient.reset();
324
+ this.clearAuthenticationTokens();
325
+ }
326
+ getTokenClaim(token, name) {
327
+ let claim = undefined;
328
+ const decoded = JWT.decode(token, { complete: true });
329
+ if (decoded) {
330
+ claim = decoded.payload[name];
331
+ }
332
+ return claim;
333
+ }
334
+ /**
335
+ * Store the authentication tokens and user id of the signed in user. This function
336
+ * is only called when a user has successfully signed in using a private key.
337
+ */
338
+ async storeTokens(uid, authTokens) {
339
+ await this.keyManager.removeItem(userKeyNames.userId);
340
+ await this.keyManager.removeItem(apiKeyNames.idToken);
341
+ await this.keyManager.removeItem(apiKeyNames.accessToken);
342
+ await this.keyManager.removeItem(apiKeyNames.refreshToken);
343
+ await this.keyManager.removeItem(apiKeyNames.tokenExpiry);
344
+ await this.keyManager.addString(userKeyNames.userId, uid);
345
+ await this.keyManager.addString(apiKeyNames.idToken, authTokens.idToken);
346
+ await this.keyManager.addString(apiKeyNames.accessToken, authTokens.accessToken);
347
+ await this.keyManager.addString(apiKeyNames.refreshToken, authTokens.refreshToken);
348
+ const decoded = JWT.decode(authTokens.idToken, { complete: true });
349
+ if (decoded) {
350
+ const tokenExpiry = decoded.payload['exp'];
351
+ await this.keyManager.addString(apiKeyNames.tokenExpiry, tokenExpiry);
352
+ }
353
+ }
354
+ async registerFederatedIdAndRefreshTokens(authTokens) {
355
+ const identityId = this.getTokenClaim(authTokens.idToken, 'custom:identityId');
356
+ if (identityId) {
357
+ return authTokens;
358
+ }
359
+ else {
360
+ await this.apiClient.registerFederatedId({
361
+ idToken: authTokens.idToken,
362
+ });
363
+ // Refresh the ID token so the identity ID is present as a claim.
364
+ const newAuthTokens = await this.refreshTokens(authTokens.refreshToken);
365
+ return newAuthTokens;
366
+ }
367
+ }
368
+ async generateRegistrationData() {
369
+ const keyId = await this.keyManager.generateKeyPair();
370
+ await this.keyManager.removeItem(userKeyNames.userKeyId);
371
+ await this.keyManager.addString(userKeyNames.userKeyId, keyId);
372
+ const publicKey = await this.keyManager.exportPublicKey(keyId);
373
+ return publicKey;
374
+ }
375
+ async getAuthTokens() {
376
+ const idToken = await this.getIdToken();
377
+ const accessToken = await this.getAccessToken();
378
+ const refreshToken = await this.getRefreshToken();
379
+ const tokenExpiry = await this.getTokenExpiry();
380
+ if (idToken && accessToken && refreshToken && tokenExpiry) {
381
+ return {
382
+ idToken: idToken,
383
+ accessToken: accessToken,
384
+ refreshToken: refreshToken,
385
+ tokenExpiry: tokenExpiry.getTime(),
386
+ };
387
+ }
388
+ else {
389
+ return undefined;
390
+ }
391
+ }
392
+ /**
393
+ * Provide a custom auth UI. This is mainly used for unit testing (optional).
394
+ */
395
+ setAuthUI(authUI) {
396
+ this.authUI = authUI;
397
+ }
398
+ /**
399
+ * Provide a custom identity provider. This is mainly used for unit testing (optional).
400
+ */
401
+ setIdentityProvider(identityProvider) {
402
+ this.identityProvider = identityProvider;
403
+ }
404
+ /**
405
+ * Provide a custom function to open the sign in url.
406
+ * This is mainly used for unit testing (optional).
407
+ */
408
+ setLaunchUriFn(launchUriFn) {
409
+ this.launchUriFn = launchUriFn;
410
+ }
411
+ /**
412
+ * Provide a custom authentication store.
413
+ * This is mainly used for unit testing (optional).
414
+ */
415
+ setAuthenticationStore(authenticationStore) {
416
+ this.authenticationStore = authenticationStore;
417
+ }
418
+ }
419
+ /**
420
+ * Convert PublicKey of any format to an RSAPublicKey format public key
421
+ *
422
+ * @param publicKey PublicKey to convert
423
+ * @returns RSAPublicKey formatted PublicKey
424
+ */
425
+ function publicKeyToRSAPublicKey(publicKey) {
426
+ if (publicKey.keyFormat === PublicKeyFormat.RSAPublicKey) {
427
+ return publicKey;
428
+ }
429
+ return {
430
+ ...publicKey,
431
+ publicKey: publicKey.publicKey.replace('MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A', ''),
432
+ keyFormat: PublicKeyFormat.RSAPublicKey,
433
+ };
434
+ }
435
+ //# sourceMappingURL=user-client.js.map