@palantir/pack.auth 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 +42 -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 +105 -0
- package/build/browser/index.js +155 -0
- package/build/browser/index.js.map +1 -0
- package/build/cjs/index.cjs +163 -0
- package/build/cjs/index.cjs.map +1 -0
- package/build/cjs/index.d.cts +189 -0
- package/build/esm/index.js +155 -0
- package/build/esm/index.js.map +1 -0
- package/build/types/__tests__/AuthModuleImpl.test.d.ts +1 -0
- package/build/types/__tests__/AuthModuleImpl.test.d.ts.map +1 -0
- package/build/types/constants/AuthModuleKey.d.ts +4 -0
- package/build/types/constants/AuthModuleKey.d.ts.map +1 -0
- package/build/types/index.d.ts +11 -0
- package/build/types/index.d.ts.map +1 -0
- package/build/types/types/AuthModule.d.ts +82 -0
- package/build/types/types/AuthModule.d.ts.map +1 -0
- package/build/types/types/AuthState.d.ts +14 -0
- package/build/types/types/AuthState.d.ts.map +1 -0
- package/build/types/types/BaseAuthService.d.ts +22 -0
- package/build/types/types/BaseAuthService.d.ts.map +1 -0
- package/build/types/types/TokenChange.d.ts +5 -0
- package/build/types/types/TokenChange.d.ts.map +1 -0
- package/build/types/types/UnverifiedTokenInfo.d.ts +13 -0
- package/build/types/types/UnverifiedTokenInfo.d.ts.map +1 -0
- package/build/types/types/UserRef.d.ts +21 -0
- package/build/types/types/UserRef.d.ts.map +1 -0
- package/build/types/utils/AuthModuleConfig.d.ts +16 -0
- package/build/types/utils/AuthModuleConfig.d.ts.map +1 -0
- package/build/types/utils/AuthModuleImpl.d.ts +25 -0
- package/build/types/utils/AuthModuleImpl.d.ts.map +1 -0
- package/package.json +67 -0
- package/src/__tests__/AuthModuleImpl.test.ts +249 -0
- package/src/constants/AuthModuleKey.ts +31 -0
- package/src/index.ts +27 -0
- package/src/types/AuthModule.ts +117 -0
- package/src/types/AuthState.ts +33 -0
- package/src/types/BaseAuthService.ts +39 -0
- package/src/types/TokenChange.ts +25 -0
- package/src/types/UnverifiedTokenInfo.ts +30 -0
- package/src/types/UserRef.ts +77 -0
- package/src/utils/AuthModuleConfig.ts +40 -0
- package/src/utils/AuthModuleImpl.ts +124 -0
- package/tsconfig.json +21 -0
- package/vitest.config.mjs +26 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type { Flavored, PackAppInternal } from "@palantir/pack.core";
|
|
18
|
+
import type { AuthModule } from "./AuthModule.js";
|
|
19
|
+
import { getAuthModule } from "./AuthModule.js";
|
|
20
|
+
|
|
21
|
+
const UserRefBrand: unique symbol = Symbol("UserRef");
|
|
22
|
+
export type UserId = Flavored<"pack:UserId">;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Reference to a user from the platform API.
|
|
26
|
+
* Provides access to user information with caching.
|
|
27
|
+
*/
|
|
28
|
+
export interface UserRef {
|
|
29
|
+
readonly userId: UserId;
|
|
30
|
+
readonly [UserRefBrand]: typeof UserRefBrand;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Get the current user data from the platform API.
|
|
34
|
+
* Results are cached to avoid excessive API calls.
|
|
35
|
+
* @param force - Force refresh of cached data
|
|
36
|
+
*/
|
|
37
|
+
readonly get: (force?: boolean) => Promise<unknown>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const INVALID_USER_ID: UserId = "INVALID_USER_REF";
|
|
41
|
+
const INVALID_USER_REF: UserRef = Object.freeze(
|
|
42
|
+
{
|
|
43
|
+
userId: INVALID_USER_ID,
|
|
44
|
+
[UserRefBrand]: UserRefBrand,
|
|
45
|
+
get: () => Promise.reject(new Error("Invalid user reference")),
|
|
46
|
+
} as const,
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
export function invalidUserRef(): UserRef {
|
|
50
|
+
return INVALID_USER_REF;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function isValidUserRef(userRef: UserRef): boolean {
|
|
54
|
+
return userRef.userId !== INVALID_USER_ID && userRef.userId !== "";
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const createUserRef = (
|
|
58
|
+
app: PackAppInternal,
|
|
59
|
+
userId: UserId,
|
|
60
|
+
): UserRef => {
|
|
61
|
+
return new UserRefImpl(app, userId);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
class UserRefImpl implements UserRef {
|
|
65
|
+
readonly userId: UserId;
|
|
66
|
+
declare readonly [UserRefBrand]: typeof UserRefBrand;
|
|
67
|
+
readonly #authModule: AuthModule;
|
|
68
|
+
|
|
69
|
+
constructor(app: PackAppInternal, userId: UserId) {
|
|
70
|
+
this.#authModule = getAuthModule(app);
|
|
71
|
+
this.userId = userId;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
get(force?: boolean): Promise<unknown> {
|
|
75
|
+
return this.#authModule.getUserData(this.userId, force);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type { ModuleConfigTuple, ModuleKey } from "@palantir/pack.core";
|
|
18
|
+
import { AUTH_MODULE_KEY } from "../constants/AuthModuleKey.js";
|
|
19
|
+
import type { AuthModule } from "../types/AuthModule.js";
|
|
20
|
+
import type { BaseAuthService } from "../types/BaseAuthService.js";
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Configuration for AuthModule initialization
|
|
24
|
+
*/
|
|
25
|
+
export interface AuthModuleConfig {
|
|
26
|
+
readonly authService: BaseAuthService;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Creates an auth module configuration tuple.
|
|
31
|
+
*
|
|
32
|
+
* @param authService - The auth service to use
|
|
33
|
+
* @returns Module configuration tuple for the auth module
|
|
34
|
+
*/
|
|
35
|
+
export function createAuthModuleConfig(
|
|
36
|
+
authService: BaseAuthService,
|
|
37
|
+
): ModuleConfigTuple<AuthModule> {
|
|
38
|
+
const config: AuthModuleConfig = { authService };
|
|
39
|
+
return [AUTH_MODULE_KEY as ModuleKey<AuthModule>, config] as const;
|
|
40
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { type PackAppInternal, type Unsubscribe } from "@palantir/pack.core";
|
|
18
|
+
import type { AuthModule } from "../types/AuthModule.js";
|
|
19
|
+
import type { AuthStateCallback } from "../types/AuthState.js";
|
|
20
|
+
import { AuthState } from "../types/AuthState.js";
|
|
21
|
+
import type { BaseAuthService } from "../types/BaseAuthService.js";
|
|
22
|
+
import type { TokenChangeCallback } from "../types/TokenChange.js";
|
|
23
|
+
import type { UserRef } from "../types/UserRef.js";
|
|
24
|
+
import { createUserRef } from "../types/UserRef.js";
|
|
25
|
+
|
|
26
|
+
export class AuthModuleImpl implements AuthModule {
|
|
27
|
+
readonly #authService: BaseAuthService;
|
|
28
|
+
private readonly app: PackAppInternal;
|
|
29
|
+
private signInPromise?: Promise<void>;
|
|
30
|
+
|
|
31
|
+
constructor(app: PackAppInternal, authService: BaseAuthService) {
|
|
32
|
+
this.app = app;
|
|
33
|
+
this.#authService = authService;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// AuthModule interface implementation
|
|
37
|
+
isAuthenticated(): boolean {
|
|
38
|
+
return this.#authService.isAuthenticated();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async getToken(): Promise<string> {
|
|
42
|
+
return this.#authService.getToken();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
getTokenOrUndefined(): string | undefined {
|
|
46
|
+
return this.#authService.getTokenOrUndefined();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async signIn(): Promise<void> {
|
|
50
|
+
if (this.signInPromise) {
|
|
51
|
+
return this.signInPromise;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
this.signInPromise = (async () => {
|
|
55
|
+
try {
|
|
56
|
+
await this.#authService.signIn();
|
|
57
|
+
} finally {
|
|
58
|
+
this.signInPromise = undefined;
|
|
59
|
+
}
|
|
60
|
+
})();
|
|
61
|
+
|
|
62
|
+
return this.signInPromise;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async signOut(): Promise<void> {
|
|
66
|
+
return this.#authService.signOut();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async refresh(): Promise<void> {
|
|
70
|
+
if (!this.#authService.refresh) {
|
|
71
|
+
throw new Error("Refresh not supported for this auth client type");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return this.#authService.refresh();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
onAuthStateChange(callback: AuthStateCallback): Unsubscribe {
|
|
78
|
+
return this.#authService.onAuthStateChange(callback);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
onTokenChange(callback: TokenChangeCallback): Unsubscribe {
|
|
82
|
+
return this.#authService.onTokenChange(callback);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async waitForAuth(): Promise<void> {
|
|
86
|
+
// If already authenticated, resolve immediately
|
|
87
|
+
if (this.isAuthenticated()) {
|
|
88
|
+
return Promise.resolve();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return new Promise((resolve, reject) => {
|
|
92
|
+
const unsubscribe = this.onAuthStateChange(event => {
|
|
93
|
+
if (event.state === AuthState.Authenticated) {
|
|
94
|
+
unsubscribe();
|
|
95
|
+
resolve();
|
|
96
|
+
} else if (event.state === AuthState.Error) {
|
|
97
|
+
unsubscribe();
|
|
98
|
+
reject(new Error("Authentication failed", { cause: event.error }));
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
getCurrentUser(): UserRef | undefined {
|
|
105
|
+
const userId = this.#authService.getCurrentUserId();
|
|
106
|
+
if (!userId) {
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
return createUserRef(this.app, userId);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async validateToken(): Promise<boolean> {
|
|
113
|
+
return this.#authService.validateToken();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async getUserData(userId: string, force?: boolean): Promise<unknown> {
|
|
117
|
+
return this.#authService.getUserData(userId, force);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
dispose(): void {
|
|
121
|
+
this.#authService.dispose();
|
|
122
|
+
this.signInPromise = undefined;
|
|
123
|
+
}
|
|
124
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "@palantir/pack.monorepo.tsconfig/base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "./build/esm",
|
|
5
|
+
"rootDir": "./src",
|
|
6
|
+
"declarationDir": "./build/types",
|
|
7
|
+
"tsBuildInfoFile": "./build/tsconfig.tsbuildinfo"
|
|
8
|
+
},
|
|
9
|
+
"include": [
|
|
10
|
+
"src/**/*"
|
|
11
|
+
],
|
|
12
|
+
"exclude": [
|
|
13
|
+
"build",
|
|
14
|
+
"dist",
|
|
15
|
+
"node_modules",
|
|
16
|
+
"test-output",
|
|
17
|
+
"**/__tests__/**/__snapshots__",
|
|
18
|
+
"**/__tests__/**/fixtures"
|
|
19
|
+
],
|
|
20
|
+
"references": []
|
|
21
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { coverageConfigDefaults, defaultExclude, defineProject } from "vitest/config";
|
|
2
|
+
|
|
3
|
+
export default defineProject({
|
|
4
|
+
test: {
|
|
5
|
+
exclude: [...defaultExclude, "**/build/**", "**/test-output/**"],
|
|
6
|
+
coverage: {
|
|
7
|
+
provider: "v8",
|
|
8
|
+
all: true,
|
|
9
|
+
enabled: true,
|
|
10
|
+
pool: "forks",
|
|
11
|
+
include: ["src/**/*.{ts,tsx}"],
|
|
12
|
+
exclude: [
|
|
13
|
+
...coverageConfigDefaults.exclude,
|
|
14
|
+
"**/*.test.{ts,tsx}",
|
|
15
|
+
"**/__tests__",
|
|
16
|
+
"build",
|
|
17
|
+
"coverage",
|
|
18
|
+
"dist",
|
|
19
|
+
"node_modules",
|
|
20
|
+
"src/index.ts",
|
|
21
|
+
"test-output",
|
|
22
|
+
"vitest.config.*",
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
});
|