@palantir/pack.auth.foundry 0.0.1-beta.1
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/.turbo/turbo-lint.log +20 -0
- package/.turbo/turbo-transpileBrowser.log +5 -0
- package/.turbo/turbo-transpileCjs.log +5 -0
- package/.turbo/turbo-transpileEsm.log +5 -0
- package/.turbo/turbo-transpileTypes.log +5 -0
- package/.turbo/turbo-typecheck.log +4 -0
- package/LICENSE.txt +13 -0
- package/README.md +159 -0
- package/build/browser/index.js +374 -0
- package/build/browser/index.js.map +1 -0
- package/build/cjs/index.cjs +381 -0
- package/build/cjs/index.cjs.map +1 -0
- package/build/cjs/index.d.cts +90 -0
- package/build/esm/index.js +374 -0
- package/build/esm/index.js.map +1 -0
- package/build/types/AuthModuleConfig.d.ts +1 -0
- package/build/types/AuthModuleConfig.d.ts.map +1 -0
- package/build/types/__tests__/AuthServiceConfidential.test.d.ts +1 -0
- package/build/types/__tests__/AuthServiceConfidential.test.d.ts.map +1 -0
- package/build/types/__tests__/AuthServicePublic.test.d.ts +1 -0
- package/build/types/__tests__/AuthServicePublic.test.d.ts.map +1 -0
- package/build/types/__tests__/AuthServiceStatic.test.d.ts +1 -0
- package/build/types/__tests__/AuthServiceStatic.test.d.ts.map +1 -0
- package/build/types/auth/AuthServiceBase.d.ts +32 -0
- package/build/types/auth/AuthServiceBase.d.ts.map +1 -0
- package/build/types/auth/AuthServiceConfidential.d.ts +20 -0
- package/build/types/auth/AuthServiceConfidential.d.ts.map +1 -0
- package/build/types/auth/AuthServicePublic.d.ts +23 -0
- package/build/types/auth/AuthServicePublic.d.ts.map +1 -0
- package/build/types/auth/AuthServiceStatic.d.ts +17 -0
- package/build/types/auth/AuthServiceStatic.d.ts.map +1 -0
- package/build/types/index.d.ts +4 -0
- package/build/types/index.d.ts.map +1 -0
- package/build/types/utils/jwtUtils.d.ts +28 -0
- package/build/types/utils/jwtUtils.d.ts.map +1 -0
- package/package.json +74 -0
- package/src/AuthModuleConfig.ts +17 -0
- package/src/__tests__/AuthServiceConfidential.test.ts +407 -0
- package/src/__tests__/AuthServicePublic.test.ts +413 -0
- package/src/__tests__/AuthServiceStatic.test.ts +341 -0
- package/src/auth/AuthServiceBase.ts +201 -0
- package/src/auth/AuthServiceConfidential.ts +96 -0
- package/src/auth/AuthServicePublic.ts +124 -0
- package/src/auth/AuthServiceStatic.ts +91 -0
- package/src/index.ts +20 -0
- package/src/utils/jwtUtils.ts +127 -0
- package/tsconfig.json +21 -0
- package/vitest.config.mjs +26 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
|
|
2
|
+
> @palantir/pack.auth.foundry@0.0.1-beta.1 lint /home/runner/work/pack/pack/packages/auth/foundry
|
|
3
|
+
> eslint ./src ; dprint check --config $(find-up dprint.json) --allow-no-files
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
/home/runner/work/pack/pack/packages/auth/foundry/src/__tests__/AuthServiceConfidential.test.ts
|
|
7
|
+
181:14 warning A method that is not declared with `this: void` may cause unintentional scoping of `this` when separated from its object.
|
|
8
|
+
Consider using an arrow function or explicitly `.bind()`ing the method to avoid calling the method with an unintended `this` value.
|
|
9
|
+
If a function does not access `this`, it can be annotated with `this: void` @typescript-eslint/unbound-method
|
|
10
|
+
388:14 warning A method that is not declared with `this: void` may cause unintentional scoping of `this` when separated from its object.
|
|
11
|
+
Consider using an arrow function or explicitly `.bind()`ing the method to avoid calling the method with an unintended `this` value.
|
|
12
|
+
If a function does not access `this`, it can be annotated with `this: void` @typescript-eslint/unbound-method
|
|
13
|
+
|
|
14
|
+
/home/runner/work/pack/pack/packages/auth/foundry/src/__tests__/AuthServiceStatic.test.ts
|
|
15
|
+
146:14 warning A method that is not declared with `this: void` may cause unintentional scoping of `this` when separated from its object.
|
|
16
|
+
Consider using an arrow function or explicitly `.bind()`ing the method to avoid calling the method with an unintended `this` value.
|
|
17
|
+
If a function does not access `this`, it can be annotated with `this: void` @typescript-eslint/unbound-method
|
|
18
|
+
|
|
19
|
+
✖ 3 problems (0 errors, 3 warnings)
|
|
20
|
+
|
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Copyright 2025 Palantir Technologies, Inc.
|
|
2
|
+
|
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License.
|
|
5
|
+
You may obtain a copy of the License at
|
|
6
|
+
|
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
|
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
See the License for the specific language governing permissions and
|
|
13
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# @palantir/pack.auth-foundry
|
|
2
|
+
|
|
3
|
+
Foundry-specific authentication implementations for PACK applications.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package provides concrete authentication services that implement the `@palantir/pack.auth` interfaces for Palantir Foundry platforms. It includes support for various authentication methods including OAuth flows and static token providers.
|
|
8
|
+
|
|
9
|
+
## Authentication Services
|
|
10
|
+
|
|
11
|
+
### StaticTokenService
|
|
12
|
+
|
|
13
|
+
For applications with pre-existing tokens (CLI tools, service accounts, etc.):
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { createStaticTokenService } from "@palantir/pack.auth-foundry";
|
|
17
|
+
|
|
18
|
+
const tokenProvider = () => Promise.resolve("your-existing-token");
|
|
19
|
+
const service = createStaticTokenService(tokenProvider, baseUrl);
|
|
20
|
+
|
|
21
|
+
// Starts authenticated immediately
|
|
22
|
+
console.log(service.isAuthenticated()); // true
|
|
23
|
+
console.log(service.isValidated()); // false (until explicitly validated)
|
|
24
|
+
|
|
25
|
+
// Validate when needed
|
|
26
|
+
await service.validateToken(); // Calls platform API to verify token
|
|
27
|
+
console.log(service.getCurrentUser()); // UserRef with platform data
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### PublicOauthService
|
|
31
|
+
|
|
32
|
+
For browser applications requiring user login:
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { createPublicOauthClient } from "@osdk/oauth";
|
|
36
|
+
import { createPublicOauthService } from "@palantir/pack.auth-foundry";
|
|
37
|
+
|
|
38
|
+
const oauthClient = createPublicOauthClient(clientId, baseUrl, redirectUrl);
|
|
39
|
+
const service = createPublicOauthService(oauthClient, baseUrl);
|
|
40
|
+
|
|
41
|
+
// Starts unauthenticated
|
|
42
|
+
console.log(service.isAuthenticated()); // false
|
|
43
|
+
|
|
44
|
+
// User must sign in
|
|
45
|
+
await service.signIn(); // Redirects to OAuth flow
|
|
46
|
+
console.log(service.isAuthenticated()); // true (after successful OAuth)
|
|
47
|
+
|
|
48
|
+
// Validate to get user data
|
|
49
|
+
await service.validateToken();
|
|
50
|
+
console.log(service.getCurrentUser()); // UserRef with platform data
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### ConfidentialOauthService
|
|
54
|
+
|
|
55
|
+
For server-side applications with client credentials:
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
import { createConfidentialOauthClient } from "@osdk/oauth";
|
|
59
|
+
import { createConfidentialOauthService } from "@palantir/pack.auth-foundry";
|
|
60
|
+
|
|
61
|
+
const oauthClient = createConfidentialOauthClient(
|
|
62
|
+
clientId,
|
|
63
|
+
clientSecret,
|
|
64
|
+
baseUrl,
|
|
65
|
+
);
|
|
66
|
+
const service = createConfidentialOauthService(oauthClient, baseUrl);
|
|
67
|
+
|
|
68
|
+
// Starts authenticated after initial token fetch
|
|
69
|
+
await service.signIn(); // Performs client credentials flow
|
|
70
|
+
console.log(service.isAuthenticated()); // true
|
|
71
|
+
|
|
72
|
+
// Validate to get user data (may not be available for service accounts)
|
|
73
|
+
await service.validateToken();
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Authentication vs Validation
|
|
77
|
+
|
|
78
|
+
All services follow the same pattern:
|
|
79
|
+
|
|
80
|
+
- **Authenticated**: Has a token available locally
|
|
81
|
+
- **Validated**: Token has been verified with the Foundry platform
|
|
82
|
+
|
|
83
|
+
This separation allows for:
|
|
84
|
+
|
|
85
|
+
- **Fast startup**: No blocking API calls during initialization
|
|
86
|
+
- **Explicit validation**: Apps control when validation occurs
|
|
87
|
+
- **Token reuse**: Works with existing/cached tokens
|
|
88
|
+
- **User data access**: Only available after validation
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
// Immediately after creation
|
|
92
|
+
service.isAuthenticated(); // May be true (static/confidential) or false (public)
|
|
93
|
+
service.isValidated(); // Always false initially
|
|
94
|
+
service.getCurrentUser(); // Always undefined initially
|
|
95
|
+
|
|
96
|
+
// After validation
|
|
97
|
+
await service.validateToken();
|
|
98
|
+
service.isValidated(); // true if token is valid
|
|
99
|
+
service.getCurrentUser(); // UserRef if validation succeeded
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Integration
|
|
103
|
+
|
|
104
|
+
This package is typically used through `@palantir/pack.app`'s `initPackApp()` function, which automatically creates the appropriate service based on the OSDK client's authentication:
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import { createClient } from "@osdk/client";
|
|
108
|
+
import {
|
|
109
|
+
createConfidentialOauthClient,
|
|
110
|
+
createPublicOauthClient,
|
|
111
|
+
} from "@osdk/oauth";
|
|
112
|
+
import { initPackApp } from "@palantir/pack.app";
|
|
113
|
+
|
|
114
|
+
// Public OAuth (browser apps)
|
|
115
|
+
const publicAuth = createPublicOauthClient(
|
|
116
|
+
"your-client-id",
|
|
117
|
+
"https://your-foundry-instance.com",
|
|
118
|
+
"http://localhost:3000/callback",
|
|
119
|
+
);
|
|
120
|
+
const publicClient = createClient(baseUrl, ontologyRid, publicAuth);
|
|
121
|
+
const app = initPackApp(publicClient, { app: { appId: "your-app" } });
|
|
122
|
+
|
|
123
|
+
// Static token (CLI/service)
|
|
124
|
+
const tokenProvider = () => Promise.resolve("your-token");
|
|
125
|
+
const tokenClient = createClient(baseUrl, ontologyRid, tokenProvider);
|
|
126
|
+
const app = initPackApp(tokenClient, { app: { appId: "your-app" } });
|
|
127
|
+
|
|
128
|
+
// Confidential OAuth (server apps)
|
|
129
|
+
const confidentialAuth = createConfidentialOauthClient(
|
|
130
|
+
"your-client-id",
|
|
131
|
+
"your-client-secret",
|
|
132
|
+
"https://your-foundry-instance.com",
|
|
133
|
+
);
|
|
134
|
+
const confidentialClient = createClient(baseUrl, ontologyRid, confidentialAuth);
|
|
135
|
+
const app = initPackApp(confidentialClient, { app: { appId: "your-app" } });
|
|
136
|
+
|
|
137
|
+
// Override auth with custom token provider
|
|
138
|
+
const app = initPackApp(client, {
|
|
139
|
+
app: { appId: "your-app" },
|
|
140
|
+
auth: customTokenProvider, // Override client's auth
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
The services handle platform-specific details like:
|
|
145
|
+
|
|
146
|
+
- OAuth flow management
|
|
147
|
+
- Token refresh and expiration
|
|
148
|
+
- Platform API integration for validation
|
|
149
|
+
- User data fetching and caching
|
|
150
|
+
- State change notifications
|
|
151
|
+
|
|
152
|
+
## Platform APIs
|
|
153
|
+
|
|
154
|
+
Token validation uses the Foundry platform API:
|
|
155
|
+
|
|
156
|
+
- **Endpoint**: `${baseUrl}/multipass/api/users/me`
|
|
157
|
+
- **Purpose**: Verify token validity and fetch user information
|
|
158
|
+
- **Caching**: User data cached for 5 minutes via UserRef
|
|
159
|
+
- **Error handling**: Network errors and invalid tokens handled gracefully
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
import { AuthState } from '@palantir/pack.auth';
|
|
2
|
+
export { createAuthModuleConfig } from '@palantir/pack.auth';
|
|
3
|
+
import { Users } from '@osdk/foundry.admin';
|
|
4
|
+
|
|
5
|
+
// src/auth/AuthServiceConfidential.ts
|
|
6
|
+
|
|
7
|
+
// src/utils/jwtUtils.ts
|
|
8
|
+
function maybeDecodeUuidClaim(value) {
|
|
9
|
+
if (!Array.isArray(value)) {
|
|
10
|
+
return void 0;
|
|
11
|
+
}
|
|
12
|
+
if (value.length === 16 && value.every((v) => typeof v === "number")) {
|
|
13
|
+
return decodeUuidBytes(value);
|
|
14
|
+
}
|
|
15
|
+
return void 0;
|
|
16
|
+
}
|
|
17
|
+
function decodeUuidBytes(bytes) {
|
|
18
|
+
if (bytes.length !== 16) {
|
|
19
|
+
return "";
|
|
20
|
+
}
|
|
21
|
+
const hex = bytes.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
22
|
+
return [hex.slice(0, 8), hex.slice(8, 12), hex.slice(12, 16), hex.slice(16, 20), hex.slice(20, 32)].join("-");
|
|
23
|
+
}
|
|
24
|
+
function parseJwtToken(token) {
|
|
25
|
+
if (!token) {
|
|
26
|
+
return void 0;
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const parts = token.split(".");
|
|
30
|
+
if (parts.length !== 3) {
|
|
31
|
+
return void 0;
|
|
32
|
+
}
|
|
33
|
+
const payload = parts[1];
|
|
34
|
+
if (!payload) {
|
|
35
|
+
return void 0;
|
|
36
|
+
}
|
|
37
|
+
const paddedPayload = payload.padEnd(payload.length + (4 - payload.length % 4) % 4, "=");
|
|
38
|
+
const decoded = JSON.parse(atob(paddedPayload));
|
|
39
|
+
return {
|
|
40
|
+
// JWT exp is seconds since epoch, convert to ms
|
|
41
|
+
expiryInstantUtc: typeof decoded.exp === "number" ? decoded.exp * 1e3 : void 0,
|
|
42
|
+
orgId: maybeDecodeUuidClaim(decoded.org),
|
|
43
|
+
sessionId: maybeDecodeUuidClaim(decoded.sid),
|
|
44
|
+
tokenId: maybeDecodeUuidClaim(decoded.jti),
|
|
45
|
+
userId: maybeDecodeUuidClaim(decoded.sub)
|
|
46
|
+
};
|
|
47
|
+
} catch {
|
|
48
|
+
return void 0;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// src/auth/AuthServiceBase.ts
|
|
53
|
+
var AuthServiceBase = class {
|
|
54
|
+
currentState;
|
|
55
|
+
isTokenValidated = false;
|
|
56
|
+
currentUserId;
|
|
57
|
+
cachedUserData;
|
|
58
|
+
stateCallbacks = /* @__PURE__ */ new Set();
|
|
59
|
+
tokenChangeCallbacks = /* @__PURE__ */ new Set();
|
|
60
|
+
currentToken;
|
|
61
|
+
app;
|
|
62
|
+
logger;
|
|
63
|
+
constructor(app, logger, initialState = AuthState.Unauthenticated) {
|
|
64
|
+
this.app = app;
|
|
65
|
+
this.logger = logger;
|
|
66
|
+
this.currentState = initialState;
|
|
67
|
+
}
|
|
68
|
+
clearUserState() {
|
|
69
|
+
this.isTokenValidated = false;
|
|
70
|
+
this.currentUserId = void 0;
|
|
71
|
+
this.cachedUserData = void 0;
|
|
72
|
+
}
|
|
73
|
+
isAuthenticated() {
|
|
74
|
+
return this.getTokenOrUndefined() != null;
|
|
75
|
+
}
|
|
76
|
+
getCurrentUserId() {
|
|
77
|
+
return this.isTokenValidated ? this.currentUserId : void 0;
|
|
78
|
+
}
|
|
79
|
+
isValidated() {
|
|
80
|
+
return this.isTokenValidated;
|
|
81
|
+
}
|
|
82
|
+
async validateToken() {
|
|
83
|
+
if (!this.isAuthenticated()) {
|
|
84
|
+
this.clearUserState();
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
if (this.app.config.isTestMode) {
|
|
88
|
+
this.isTokenValidated = true;
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
const user = await Users.getCurrent(this.app.config.osdkClient);
|
|
93
|
+
this.isTokenValidated = true;
|
|
94
|
+
this.cachedUserData = user;
|
|
95
|
+
this.currentUserId = user.id;
|
|
96
|
+
return true;
|
|
97
|
+
} catch (error) {
|
|
98
|
+
this.logger.error("Token validation failed", error);
|
|
99
|
+
this.clearUserState();
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
onAuthStateChange(callback) {
|
|
104
|
+
this.stateCallbacks.add(callback);
|
|
105
|
+
try {
|
|
106
|
+
callback({
|
|
107
|
+
state: this.currentState
|
|
108
|
+
});
|
|
109
|
+
} catch (err) {
|
|
110
|
+
this.logger.error("Error in auth state callback:", err);
|
|
111
|
+
}
|
|
112
|
+
return () => {
|
|
113
|
+
this.stateCallbacks.delete(callback);
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
onTokenChange(callback) {
|
|
117
|
+
this.tokenChangeCallbacks.add(callback);
|
|
118
|
+
const token = this.getTokenOrUndefined();
|
|
119
|
+
if (token != null) {
|
|
120
|
+
const info = parseJwtToken(token) ?? {};
|
|
121
|
+
try {
|
|
122
|
+
callback(token, info);
|
|
123
|
+
} catch (err) {
|
|
124
|
+
this.logger.error("Error in token change callback:", err);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return () => {
|
|
128
|
+
this.tokenChangeCallbacks.delete(callback);
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
getCurrentState() {
|
|
132
|
+
return this.currentState;
|
|
133
|
+
}
|
|
134
|
+
async getUserData(userId, force) {
|
|
135
|
+
if (!this.isTokenValidated || !this.currentUserId || this.currentUserId !== userId) {
|
|
136
|
+
throw new Error(`User data not available for userId: ${userId}`);
|
|
137
|
+
}
|
|
138
|
+
if (!force && this.cachedUserData) {
|
|
139
|
+
return this.cachedUserData;
|
|
140
|
+
}
|
|
141
|
+
if (this.app.config.isTestMode) {
|
|
142
|
+
throw new Error("Cannot refresh user data in test mode");
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
const user = await Users.get(this.app.config.osdkClient, userId);
|
|
146
|
+
this.cachedUserData = user;
|
|
147
|
+
return user;
|
|
148
|
+
} catch (error) {
|
|
149
|
+
this.logger.error("Failed to refresh user data", error);
|
|
150
|
+
throw new Error("Failed to refresh user data");
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
dispose() {
|
|
154
|
+
this.stateCallbacks.clear();
|
|
155
|
+
this.tokenChangeCallbacks.clear();
|
|
156
|
+
this.clearUserState();
|
|
157
|
+
}
|
|
158
|
+
notifyTokenChange(token) {
|
|
159
|
+
const info = (token != null ? parseJwtToken(token) : void 0) ?? {};
|
|
160
|
+
this.tokenChangeCallbacks.forEach((callback) => {
|
|
161
|
+
try {
|
|
162
|
+
callback(token, info);
|
|
163
|
+
} catch (err) {
|
|
164
|
+
this.logger.error("Error in token change callback:", err);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
updateState(newState, error) {
|
|
169
|
+
const previousState = this.currentState;
|
|
170
|
+
this.currentState = newState;
|
|
171
|
+
const event = {
|
|
172
|
+
previousState,
|
|
173
|
+
state: newState,
|
|
174
|
+
error
|
|
175
|
+
};
|
|
176
|
+
this.stateCallbacks.forEach((callback) => {
|
|
177
|
+
try {
|
|
178
|
+
callback(event);
|
|
179
|
+
} catch (err) {
|
|
180
|
+
this.logger.error("Error in auth state callback:", err);
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
// src/auth/AuthServiceConfidential.ts
|
|
187
|
+
var AuthServiceConfidential = class extends AuthServiceBase {
|
|
188
|
+
oauthClient;
|
|
189
|
+
constructor(app, oauthClient) {
|
|
190
|
+
const initialState = oauthClient.getTokenOrUndefined() ? AuthState.Authenticated : AuthState.Unauthenticated;
|
|
191
|
+
super(app, app.config.logger.child({}, {
|
|
192
|
+
msgPrefix: "AuthServiceConfidential"
|
|
193
|
+
}), initialState);
|
|
194
|
+
this.oauthClient = oauthClient;
|
|
195
|
+
this.oauthClient.addEventListener("signIn", this.signInHandler);
|
|
196
|
+
this.oauthClient.addEventListener("signOut", this.signOutHandler);
|
|
197
|
+
}
|
|
198
|
+
async getToken() {
|
|
199
|
+
return this.oauthClient();
|
|
200
|
+
}
|
|
201
|
+
signInHandler = () => {
|
|
202
|
+
this.updateState(AuthState.Authenticated);
|
|
203
|
+
const token = this.getTokenOrUndefined();
|
|
204
|
+
this.notifyTokenChange(token);
|
|
205
|
+
};
|
|
206
|
+
signOutHandler = () => {
|
|
207
|
+
this.updateState(AuthState.Unauthenticated);
|
|
208
|
+
this.notifyTokenChange(void 0);
|
|
209
|
+
};
|
|
210
|
+
getTokenOrUndefined() {
|
|
211
|
+
return this.oauthClient.getTokenOrUndefined();
|
|
212
|
+
}
|
|
213
|
+
async signIn() {
|
|
214
|
+
try {
|
|
215
|
+
this.updateState(AuthState.Authenticating);
|
|
216
|
+
await this.oauthClient.signIn();
|
|
217
|
+
} catch (error) {
|
|
218
|
+
this.updateState(AuthState.Error, error instanceof Error ? error : new Error(String(error)));
|
|
219
|
+
throw error;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
async signOut() {
|
|
223
|
+
try {
|
|
224
|
+
this.clearUserState();
|
|
225
|
+
await this.oauthClient.signOut();
|
|
226
|
+
} catch (error) {
|
|
227
|
+
this.updateState(AuthState.Error, error instanceof Error ? error : new Error(String(error)));
|
|
228
|
+
throw error;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
dispose() {
|
|
232
|
+
this.oauthClient.removeEventListener("signIn", this.signInHandler);
|
|
233
|
+
this.oauthClient.removeEventListener("signOut", this.signOutHandler);
|
|
234
|
+
super.dispose();
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
function createConfidentialOauthService(app, oauthClient) {
|
|
238
|
+
return new AuthServiceConfidential(app, oauthClient);
|
|
239
|
+
}
|
|
240
|
+
var AuthServicePublic = class extends AuthServiceBase {
|
|
241
|
+
hasInitialized = false;
|
|
242
|
+
oauthClient;
|
|
243
|
+
constructor(app, oauthClient) {
|
|
244
|
+
super(app, app.config.logger.child({}, {
|
|
245
|
+
msgPrefix: "AuthServicePublic"
|
|
246
|
+
}), AuthState.Initializing);
|
|
247
|
+
this.oauthClient = oauthClient;
|
|
248
|
+
this.oauthClient.addEventListener("signIn", this.signInHandler);
|
|
249
|
+
this.oauthClient.addEventListener("signOut", this.signOutHandler);
|
|
250
|
+
this.oauthClient.addEventListener("refresh", this.refreshHandler);
|
|
251
|
+
}
|
|
252
|
+
async getToken() {
|
|
253
|
+
return this.oauthClient();
|
|
254
|
+
}
|
|
255
|
+
signInHandler = () => {
|
|
256
|
+
const token = this.getTokenOrUndefined();
|
|
257
|
+
this.notifyTokenChange(token);
|
|
258
|
+
this.updateState(AuthState.Authenticated);
|
|
259
|
+
};
|
|
260
|
+
signOutHandler = () => {
|
|
261
|
+
this.notifyTokenChange(void 0);
|
|
262
|
+
this.updateState(AuthState.Unauthenticated);
|
|
263
|
+
};
|
|
264
|
+
refreshHandler = () => {
|
|
265
|
+
const token = this.getTokenOrUndefined();
|
|
266
|
+
this.notifyTokenChange(token);
|
|
267
|
+
this.updateState(AuthState.Authenticated);
|
|
268
|
+
};
|
|
269
|
+
getTokenOrUndefined() {
|
|
270
|
+
return this.oauthClient.getTokenOrUndefined();
|
|
271
|
+
}
|
|
272
|
+
onAuthStateChange(callback) {
|
|
273
|
+
const unsubscribe = super.onAuthStateChange(callback);
|
|
274
|
+
if (!this.hasInitialized && this.currentState === AuthState.Initializing) {
|
|
275
|
+
this.hasInitialized = true;
|
|
276
|
+
void this.signIn().catch(() => {
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
return unsubscribe;
|
|
280
|
+
}
|
|
281
|
+
async signIn() {
|
|
282
|
+
try {
|
|
283
|
+
this.updateState(AuthState.Authenticating);
|
|
284
|
+
await this.oauthClient.signIn();
|
|
285
|
+
} catch (error) {
|
|
286
|
+
this.updateState(AuthState.Error, error instanceof Error ? error : new Error(String(error)));
|
|
287
|
+
throw error;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
async signOut() {
|
|
291
|
+
try {
|
|
292
|
+
this.clearUserState();
|
|
293
|
+
await this.oauthClient.signOut();
|
|
294
|
+
} catch (error) {
|
|
295
|
+
this.updateState(AuthState.Error, error instanceof Error ? error : new Error(String(error)));
|
|
296
|
+
throw error;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
async refresh() {
|
|
300
|
+
try {
|
|
301
|
+
await this.oauthClient.refresh();
|
|
302
|
+
} catch (error) {
|
|
303
|
+
this.updateState(AuthState.Error, error instanceof Error ? error : new Error(String(error)));
|
|
304
|
+
throw error;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
dispose() {
|
|
308
|
+
this.oauthClient.removeEventListener("signIn", this.signInHandler);
|
|
309
|
+
this.oauthClient.removeEventListener("signOut", this.signOutHandler);
|
|
310
|
+
this.oauthClient.removeEventListener("refresh", this.refreshHandler);
|
|
311
|
+
super.dispose();
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
function createPublicOauthService(app, oauthClient) {
|
|
315
|
+
return new AuthServicePublic(app, oauthClient);
|
|
316
|
+
}
|
|
317
|
+
var AuthServiceStatic = class extends AuthServiceBase {
|
|
318
|
+
tokenProvider;
|
|
319
|
+
latestToken;
|
|
320
|
+
constructor(app, tokenProvider) {
|
|
321
|
+
super(app, app.config.logger.child({}, {
|
|
322
|
+
msgPrefix: "AuthServiceStatic"
|
|
323
|
+
}), AuthState.Unauthenticated);
|
|
324
|
+
this.tokenProvider = tokenProvider;
|
|
325
|
+
void this.getToken().catch(() => {
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
async getToken() {
|
|
329
|
+
try {
|
|
330
|
+
const token = await this.tokenProvider();
|
|
331
|
+
if (this.latestToken !== token) {
|
|
332
|
+
this.latestToken = token;
|
|
333
|
+
this.notifyTokenChange(token);
|
|
334
|
+
if (this.currentState !== AuthState.Authenticated) {
|
|
335
|
+
this.updateState(AuthState.Authenticated);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return token;
|
|
339
|
+
} catch (error) {
|
|
340
|
+
if (this.latestToken !== void 0) {
|
|
341
|
+
this.latestToken = void 0;
|
|
342
|
+
this.notifyTokenChange(void 0);
|
|
343
|
+
}
|
|
344
|
+
this.updateState(AuthState.Error, error);
|
|
345
|
+
throw error;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
getTokenOrUndefined() {
|
|
349
|
+
return this.latestToken;
|
|
350
|
+
}
|
|
351
|
+
isAuthenticated() {
|
|
352
|
+
return this.latestToken != null;
|
|
353
|
+
}
|
|
354
|
+
signIn() {
|
|
355
|
+
return Promise.resolve();
|
|
356
|
+
}
|
|
357
|
+
signOut() {
|
|
358
|
+
this.clearUserState();
|
|
359
|
+
this.latestToken = void 0;
|
|
360
|
+
this.updateState(AuthState.Unauthenticated);
|
|
361
|
+
return Promise.reject(new Error("Sign out not supported for static token providers"));
|
|
362
|
+
}
|
|
363
|
+
dispose() {
|
|
364
|
+
super.dispose();
|
|
365
|
+
this.latestToken = void 0;
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
function createStaticTokenService(app, tokenProvider) {
|
|
369
|
+
return new AuthServiceStatic(app, tokenProvider);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
export { createConfidentialOauthService, createPublicOauthService, createStaticTokenService };
|
|
373
|
+
//# sourceMappingURL=index.js.map
|
|
374
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/jwtUtils.ts","../../src/auth/AuthServiceBase.ts","../../src/auth/AuthServiceConfidential.ts","../../src/auth/AuthServicePublic.ts","../../src/auth/AuthServiceStatic.ts"],"names":["AuthState"],"mappings":"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","file":"index.js","sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Decode a Palantir-specific JWT claim that stores UUIDs as 16-byte arrays.\n * These are the sub, sid, jti, and org claims.\n */\nfunction maybeDecodeUuidClaim(value) {\n if (!Array.isArray(value)) {\n return undefined;\n }\n if (value.length === 16 && value.every(v => typeof v === \"number\")) {\n // Convert 16-byte array to UUID string\n return decodeUuidBytes(value);\n }\n return undefined;\n}\n\n/**\n * Convert a 16-byte array to UUID string format.\n * Based on Palantir's UUID encoding format.\n */\nfunction decodeUuidBytes(bytes) {\n if (bytes.length !== 16) {\n return \"\";\n }\n\n // Convert bytes to hex string\n const hex = bytes.map(b => b.toString(16).padStart(2, \"0\")).join(\"\");\n\n // Format as UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n return [hex.slice(0, 8), hex.slice(8, 12), hex.slice(12, 16), hex.slice(16, 20), hex.slice(20, 32)].join(\"-\");\n}\n\n/**\n * Represents the parsed payload from a JWT token (unverified).\n * The information provided should not be used for security-sensitive\n * applications unless verified through some other process.\n */\n\n/**\n * Parse JWT token to extract unverified claims including userId, sessionId, tokenId, organizationId, and expiry.\n * This does NOT verify the token signature - it only extracts payload data.\n *\n * @param token - JWT token string\n * @returns Unverified token info or undefined if parsing fails\n */\nexport function parseJwtToken(token) {\n if (!token) {\n return undefined;\n }\n try {\n // JWT tokens have 3 parts separated by dots: header.payload.signature\n const parts = token.split(\".\");\n if (parts.length !== 3) {\n return undefined;\n }\n\n // Decode the payload (second part)\n const payload = parts[1];\n if (!payload) {\n return undefined;\n }\n\n // Add padding if needed for base64 decoding\n const paddedPayload = payload.padEnd(payload.length + (4 - payload.length % 4) % 4, \"=\");\n const decoded = JSON.parse(atob(paddedPayload));\n return {\n // JWT exp is seconds since epoch, convert to ms\n expiryInstantUtc: typeof decoded.exp === \"number\" ? decoded.exp * 1000 : undefined,\n orgId: maybeDecodeUuidClaim(decoded.org),\n sessionId: maybeDecodeUuidClaim(decoded.sid),\n tokenId: maybeDecodeUuidClaim(decoded.jti),\n userId: maybeDecodeUuidClaim(decoded.sub)\n };\n } catch {\n return undefined;\n }\n}\n\n/**\n * Check if a JWT token is expired based on its exp claim (unverified).\n *\n * @param tokenInfo - Unverified token info\n * @returns true if token is expired, false if valid or no expiry info\n */\nexport function isTokenExpired(tokenInfo) {\n if (!tokenInfo.expiryInstantUtc) {\n return false; // No expiry info, assume valid\n }\n const now = Date.now();\n return tokenInfo.expiryInstantUtc < now;\n}","/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Users } from \"@osdk/foundry.admin\";\nimport { AuthState } from \"@palantir/pack.auth\";\nimport { parseJwtToken } from \"../utils/jwtUtils.js\";\nexport class AuthServiceBase {\n currentState;\n isTokenValidated = false;\n currentUserId;\n cachedUserData;\n stateCallbacks = new Set();\n tokenChangeCallbacks = new Set();\n currentToken;\n app;\n logger;\n constructor(app, logger, initialState = AuthState.Unauthenticated) {\n this.app = app;\n this.logger = logger;\n this.currentState = initialState;\n }\n clearUserState() {\n this.isTokenValidated = false;\n this.currentUserId = undefined;\n this.cachedUserData = undefined;\n }\n isAuthenticated() {\n return this.getTokenOrUndefined() != null;\n }\n getCurrentUserId() {\n return this.isTokenValidated ? this.currentUserId : undefined;\n }\n isValidated() {\n return this.isTokenValidated;\n }\n async validateToken() {\n if (!this.isAuthenticated()) {\n this.clearUserState();\n return false;\n }\n if (this.app.config.isTestMode) {\n this.isTokenValidated = true;\n return true;\n }\n try {\n const user = await Users.getCurrent(this.app.config.osdkClient);\n this.isTokenValidated = true;\n this.cachedUserData = user;\n this.currentUserId = user.id;\n return true;\n } catch (error) {\n this.logger.error(\"Token validation failed\", error);\n this.clearUserState();\n return false;\n }\n }\n onAuthStateChange(callback) {\n this.stateCallbacks.add(callback);\n try {\n callback({\n state: this.currentState\n });\n } catch (err) {\n this.logger.error(\"Error in auth state callback:\", err);\n }\n return () => {\n this.stateCallbacks.delete(callback);\n };\n }\n onTokenChange(callback) {\n this.tokenChangeCallbacks.add(callback);\n\n // Immediately notify with current token if available\n const token = this.getTokenOrUndefined();\n if (token != null) {\n const info = parseJwtToken(token) ?? {};\n try {\n callback(token, info);\n } catch (err) {\n this.logger.error(\"Error in token change callback:\", err);\n }\n }\n return () => {\n this.tokenChangeCallbacks.delete(callback);\n };\n }\n getCurrentState() {\n return this.currentState;\n }\n async getUserData(userId, force) {\n if (!this.isTokenValidated || !this.currentUserId || this.currentUserId !== userId) {\n throw new Error(`User data not available for userId: ${userId}`);\n }\n if (!force && this.cachedUserData) {\n return this.cachedUserData;\n }\n if (this.app.config.isTestMode) {\n throw new Error(\"Cannot refresh user data in test mode\");\n }\n try {\n // TODO: debounce and use Users.getBatch for efficiency when looking up multiple users\n const user = await Users.get(this.app.config.osdkClient, userId);\n this.cachedUserData = user;\n return user;\n } catch (error) {\n this.logger.error(\"Failed to refresh user data\", error);\n throw new Error(\"Failed to refresh user data\");\n }\n }\n dispose() {\n this.stateCallbacks.clear();\n this.tokenChangeCallbacks.clear();\n this.clearUserState();\n }\n notifyTokenChange(token) {\n const info = (token != null ? parseJwtToken(token) : undefined) ?? {};\n this.tokenChangeCallbacks.forEach(callback => {\n try {\n callback(token, info);\n } catch (err) {\n this.logger.error(\"Error in token change callback:\", err);\n }\n });\n }\n updateState(newState, error) {\n const previousState = this.currentState;\n this.currentState = newState;\n const event = {\n previousState,\n state: newState,\n error\n };\n this.stateCallbacks.forEach(callback => {\n try {\n callback(event);\n } catch (err) {\n this.logger.error(\"Error in auth state callback:\", err);\n }\n });\n }\n}","/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AuthState } from \"@palantir/pack.auth\";\nimport { AuthServiceBase } from \"./AuthServiceBase.js\";\nexport class AuthServiceConfidential extends AuthServiceBase {\n oauthClient;\n constructor(app, oauthClient) {\n const initialState = oauthClient.getTokenOrUndefined() ? AuthState.Authenticated : AuthState.Unauthenticated;\n super(app, app.config.logger.child({}, {\n msgPrefix: \"AuthServiceConfidential\"\n }), initialState);\n this.oauthClient = oauthClient;\n this.oauthClient.addEventListener(\"signIn\", this.signInHandler);\n this.oauthClient.addEventListener(\"signOut\", this.signOutHandler);\n }\n async getToken() {\n return this.oauthClient();\n }\n signInHandler = () => {\n this.updateState(AuthState.Authenticated);\n const token = this.getTokenOrUndefined();\n this.notifyTokenChange(token);\n };\n signOutHandler = () => {\n this.updateState(AuthState.Unauthenticated);\n this.notifyTokenChange(undefined);\n };\n getTokenOrUndefined() {\n return this.oauthClient.getTokenOrUndefined();\n }\n async signIn() {\n try {\n this.updateState(AuthState.Authenticating);\n await this.oauthClient.signIn();\n } catch (error) {\n this.updateState(AuthState.Error, error instanceof Error ? error : new Error(String(error)));\n throw error;\n }\n }\n async signOut() {\n try {\n this.clearUserState();\n await this.oauthClient.signOut();\n } catch (error) {\n this.updateState(AuthState.Error, error instanceof Error ? error : new Error(String(error)));\n throw error;\n }\n }\n dispose() {\n this.oauthClient.removeEventListener(\"signIn\", this.signInHandler);\n this.oauthClient.removeEventListener(\"signOut\", this.signOutHandler);\n super.dispose();\n }\n}\n\n/**\n * Creates a confidential OAuth auth service that wraps a ConfidentialOauthClient\n */\nexport function createConfidentialOauthService(app, oauthClient) {\n return new AuthServiceConfidential(app, oauthClient);\n}","/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AuthState } from \"@palantir/pack.auth\";\nimport { AuthServiceBase } from \"./AuthServiceBase.js\";\nexport class AuthServicePublic extends AuthServiceBase {\n hasInitialized = false;\n oauthClient;\n constructor(app, oauthClient) {\n super(app, app.config.logger.child({}, {\n msgPrefix: \"AuthServicePublic\"\n }), AuthState.Initializing);\n this.oauthClient = oauthClient;\n this.oauthClient.addEventListener(\"signIn\", this.signInHandler);\n this.oauthClient.addEventListener(\"signOut\", this.signOutHandler);\n this.oauthClient.addEventListener(\"refresh\", this.refreshHandler);\n }\n async getToken() {\n return this.oauthClient();\n }\n signInHandler = () => {\n const token = this.getTokenOrUndefined();\n this.notifyTokenChange(token);\n this.updateState(AuthState.Authenticated);\n };\n signOutHandler = () => {\n this.notifyTokenChange(undefined);\n this.updateState(AuthState.Unauthenticated);\n };\n refreshHandler = () => {\n const token = this.getTokenOrUndefined();\n this.notifyTokenChange(token);\n this.updateState(AuthState.Authenticated);\n };\n getTokenOrUndefined() {\n return this.oauthClient.getTokenOrUndefined();\n }\n onAuthStateChange(callback) {\n const unsubscribe = super.onAuthStateChange(callback);\n if (!this.hasInitialized && this.currentState === AuthState.Initializing) {\n this.hasInitialized = true;\n void this.signIn().catch(() => {\n // Don't allow unhandled rejection to bubble up, mostly for testing.\n // Note the signIn method will log errors and throw for promise consumers,\n // but we don't need to handle anything here.\n });\n }\n return unsubscribe;\n }\n async signIn() {\n try {\n this.updateState(AuthState.Authenticating);\n await this.oauthClient.signIn();\n } catch (error) {\n this.updateState(AuthState.Error, error instanceof Error ? error : new Error(String(error)));\n throw error;\n }\n }\n async signOut() {\n try {\n this.clearUserState();\n await this.oauthClient.signOut();\n } catch (error) {\n this.updateState(AuthState.Error, error instanceof Error ? error : new Error(String(error)));\n throw error;\n }\n }\n async refresh() {\n try {\n await this.oauthClient.refresh();\n } catch (error) {\n this.updateState(AuthState.Error, error instanceof Error ? error : new Error(String(error)));\n throw error;\n }\n }\n dispose() {\n this.oauthClient.removeEventListener(\"signIn\", this.signInHandler);\n this.oauthClient.removeEventListener(\"signOut\", this.signOutHandler);\n this.oauthClient.removeEventListener(\"refresh\", this.refreshHandler);\n super.dispose();\n }\n}\n\n/**\n * Creates a public OAuth auth service that wraps a PublicOauthClient\n */\nexport function createPublicOauthService(app, oauthClient) {\n return new AuthServicePublic(app, oauthClient);\n}","/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AuthState } from \"@palantir/pack.auth\";\nimport { AuthServiceBase } from \"./AuthServiceBase.js\";\nexport class AuthServiceStatic extends AuthServiceBase {\n tokenProvider;\n latestToken;\n constructor(app, tokenProvider) {\n super(app, app.config.logger.child({}, {\n msgPrefix: \"AuthServiceStatic\"\n }), AuthState.Unauthenticated);\n this.tokenProvider = tokenProvider;\n void this.getToken().catch(() => {});\n }\n async getToken() {\n try {\n const token = await this.tokenProvider();\n if (this.latestToken !== token) {\n this.latestToken = token;\n this.notifyTokenChange(token);\n if (this.currentState !== AuthState.Authenticated) {\n this.updateState(AuthState.Authenticated);\n }\n }\n return token;\n } catch (error) {\n if (this.latestToken !== undefined) {\n this.latestToken = undefined;\n this.notifyTokenChange(undefined);\n }\n this.updateState(AuthState.Error, error);\n throw error;\n }\n }\n getTokenOrUndefined() {\n return this.latestToken;\n }\n isAuthenticated() {\n return this.latestToken != null;\n }\n signIn() {\n return Promise.resolve();\n }\n signOut() {\n this.clearUserState();\n this.latestToken = undefined;\n this.updateState(AuthState.Unauthenticated);\n return Promise.reject(new Error(\"Sign out not supported for static token providers\"));\n }\n dispose() {\n super.dispose();\n this.latestToken = undefined;\n }\n}\n\n/**\n * Creates a static token auth service for CLI/service scenarios where a token is provided externally.\n */\nexport function createStaticTokenService(app, tokenProvider) {\n return new AuthServiceStatic(app, tokenProvider);\n}"]}
|