@abapify/adt-playwright 0.4.33 → 0.4.36

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/README.md CHANGED
@@ -1,348 +1,38 @@
1
1
  # @abapify/adt-playwright
2
2
 
3
- [![version](https://img.shields.io/github/package-json/v/abapify/adt-cli?filename=packages/adt-playwright/package.json)](https://github.com/abapify/adt-cli/pkgs/npm/%40abapify%2Fadt-playwright)
3
+ [![npm](https://img.shields.io/npm/v/%40abapify%2Fadt-playwright)](https://www.npmjs.com/package/@abapify/adt-playwright)
4
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/abapify/adt-cli/blob/main/LICENSE)
4
5
 
5
- Playwright-based SSO authentication plugin for SAP ADT systems. Modern alternative to Puppeteer with better API and maintenance.
6
+ Playwright-based SSO authentication plugin for ADT client.
6
7
 
7
- ## Features
8
-
9
- - 🔐 **SSO/IDP Support** - Works with Okta, Azure AD, and other identity providers
10
- - 💾 **Session Persistence** - Reuse Okta tokens across runs
11
- - 🎭 **Playwright-powered** - Modern, reliable browser automation
12
- - ⚡ **Fast** - Skip login when session is still valid
13
- - 🔄 **AuthManager Integration** - Works seamlessly with ADT CLI
14
-
15
- ## Installation
8
+ ## Install
16
9
 
17
10
  ```bash
18
- npm install @abapify/adt-playwright playwright
11
+ npm install @abapify/adt-playwright
19
12
  ```
20
13
 
21
- ## Quick Start
14
+ ## Usage
22
15
 
23
- ```typescript
16
+ ```ts
24
17
  // adt.config.ts
25
18
  import { defineConfig } from '@abapify/adt-config';
26
19
  import { withPlaywright } from '@abapify/adt-playwright';
27
20
 
28
21
  export default withPlaywright(
29
- defineConfig({
30
- destinations: {
31
- DEV: 'https://sap-dev.example.com',
32
- PROD: 'https://sap-prod.example.com',
33
- },
34
- }),
35
- {
36
- userDataDir: true, // Enable session persistence
37
- headless: false, // Show browser window for SSO
38
- ignoreHTTPSErrors: true, // Ignore self-signed certificates
39
- requiredCookies: ['SAP_SESSIONID_*', 'sap-usercontext'],
40
- },
41
- );
42
- ```
43
-
44
- ## Direct API Usage
45
-
46
- ```typescript
47
- import { playwrightAuth, toCookieHeader } from '@abapify/adt-playwright';
48
-
49
- // Authenticate - opens browser for SSO login
50
- const credentials = await playwrightAuth.authenticate({
51
- url: 'https://sap-system.example.com',
52
- userDataDir: true,
53
- headless: false,
54
- requiredCookies: ['SAP_SESSIONID_*', 'sap-usercontext'],
55
- });
56
-
57
- // Convert to Cookie header for HTTP requests
58
- const cookieHeader = toCookieHeader(credentials);
59
-
60
- // Test if session is still valid
61
- const result = await playwrightAuth.test(credentials);
62
- console.log(result.valid); // true/false
63
- ```
64
-
65
- ## How It Works
66
-
67
- ```
68
- ┌─────────────────────────────────────────────────────────────────┐
69
- │ Authentication Flow │
70
- ├─────────────────────────────────────────────────────────────────┤
71
- │ │
72
- │ 1. Launch Browser ──► 2. Navigate to SAP ──► 3. SSO Redirect │
73
- │ │ │ │
74
- │ ▼ ▼ │
75
- │ [Persistent Profile] [User completes login] │
76
- │ │ │ │
77
- │ ▼ ▼ │
78
- │ 4. Check Session ◄─────────────────────── 5. Capture Cookies │
79
- │ │ │ │
80
- │ ▼ ▼ │
81
- │ [Valid? Skip login] [Return credentials] │
82
- │ │
83
- └─────────────────────────────────────────────────────────────────┘
84
- ```
85
-
86
- 1. **Launch Browser** - Opens Chromium with optional persistent profile
87
- 2. **Navigate to SAP** - Goes to ADT discovery endpoint
88
- 3. **SSO Redirect** - Browser redirects to Okta/IDP
89
- 4. **User Login** - User completes 2FA/SSO in browser
90
- 5. **Capture Cookies** - Waits for required cookies, extracts session
91
-
92
- ## Options
93
-
94
- ```typescript
95
- interface PlaywrightAuthOptions {
96
- /** SAP system URL (required) */
97
- url: string;
98
-
99
- /** Hide browser window (default: false) */
100
- headless?: boolean;
101
-
102
- /** Login timeout in ms (default: 300000 = 5 minutes) */
103
- timeout?: number;
104
-
105
- /** Custom user agent */
106
- userAgent?: string;
107
-
108
- /**
109
- * Cookie patterns to wait for before completing auth.
110
- * Supports wildcards: 'SAP_SESSIONID_*'
111
- * @example ['SAP_SESSIONID_*', 'sap-usercontext']
112
- */
113
- requiredCookies?: string[];
114
-
115
- /**
116
- * Session persistence directory.
117
- * - true: Use default (~/.adt/browser-profile)
118
- * - string: Custom path
119
- * - false/undefined: No persistence
120
- */
121
- userDataDir?: string | boolean;
122
-
123
- /** Ignore HTTPS errors (default: true) */
124
- ignoreHTTPSErrors?: boolean;
125
- }
126
- ```
127
-
128
- ## Session Persistence
129
-
130
- Enable `userDataDir` to persist browser state across runs:
131
-
132
- ```typescript
133
- // Use default profile directory (~/.adt/browser-profile)
134
- {
135
- userDataDir: true;
136
- }
137
-
138
- // Use custom directory
139
- {
140
- userDataDir: '/path/to/profile';
141
- }
142
-
143
- // No persistence (fresh session each time)
144
- {
145
- userDataDir: false;
146
- }
147
- ```
148
-
149
- ### Benefits
150
-
151
- - **Skip repeated logins** - Okta tokens persist across runs
152
- - **Faster authentication** - Only refresh SAP cookies when needed
153
- - **Better UX** - Same experience as using a regular browser
154
-
155
- ### How It Works
156
-
157
- 1. **First run**: User completes full SSO login → profile saved
158
- 2. **Subsequent runs**:
159
- - ✅ **Okta valid**: Auto-authenticates, extracts SAP cookies
160
- - ❌ **Okta expired**: Prompts for re-login
161
-
162
- ### Clearing Sessions
163
-
164
- ```bash
165
- # Remove default profile
166
- rm -rf ~/.adt/browser-profile
167
-
168
- # Or remove custom profile
169
- rm -rf /path/to/custom/profile
170
- ```
171
-
172
- ## Configuration Patterns
173
-
174
- ### Pattern 1: All Destinations with Playwright
175
-
176
- ```typescript
177
- import { defineConfig } from '@abapify/adt-config';
178
- import { withPlaywright } from '@abapify/adt-playwright';
179
-
180
- export default withPlaywright(
181
- defineConfig({
182
- destinations: {
183
- DEV: 'https://sap-dev.example.com',
184
- QAS: 'https://sap-qas.example.com',
185
- PROD: 'https://sap-prod.example.com',
186
- },
187
- }),
188
- {
189
- userDataDir: true,
190
- headless: false,
191
- requiredCookies: ['SAP_SESSIONID_*', 'sap-usercontext'],
192
- },
22
+ defineConfig({ destinations: { DEV: 'https://sap-dev.example.com' } }),
193
23
  );
194
24
  ```
195
25
 
196
- ### Pattern 2: Per-Destination Options
197
-
198
- ```typescript
199
- import { defineConfig } from '@abapify/adt-config';
200
- import { playwright } from '@abapify/adt-playwright';
201
-
202
- export default defineConfig({
203
- destinations: {
204
- DEV: playwright({
205
- url: 'https://sap-dev.example.com',
206
- timeout: 60000,
207
- }),
208
- PROD: playwright({
209
- url: 'https://sap-prod.example.com',
210
- requiredCookies: ['SAP_SESSIONID_*', 'MYSAPSSO2'],
211
- }),
212
- },
213
- });
214
- ```
215
-
216
- ### Pattern 3: Mixed Auth Types
217
-
218
- ```typescript
219
- import { defineConfig } from '@abapify/adt-config';
220
- import { basic } from '@abapify/adt-auth/plugins/basic';
221
- import { playwright } from '@abapify/adt-playwright';
222
-
223
- export default defineConfig({
224
- destinations: {
225
- // Basic auth for dev
226
- DEV: basic({
227
- url: 'https://dev.example.com',
228
- username: 'developer',
229
- password: process.env.SAP_PASSWORD,
230
- }),
231
- // Playwright for production (SSO)
232
- PROD: playwright({
233
- url: 'https://prod.example.com',
234
- userDataDir: true,
235
- }),
236
- },
237
- });
238
- ```
239
-
240
- ## CLI Usage
241
-
242
- ```bash
243
- # Login to a system
244
- npx adt auth login --sid DEV
245
-
246
- # Login with specific destination
247
- npx adt auth login --sid PROD
248
-
249
- # Check session status
250
- npx adt auth status
251
-
252
- # Logout
253
- npx adt auth logout --sid DEV
254
- ```
255
-
256
- ## Architecture
257
-
258
- This package is a thin wrapper around `@abapify/browser-auth`:
259
-
260
- ```
261
- @abapify/browser-auth (core logic)
262
- ├── Event-driven auth flow
263
- ├── Cookie utilities
264
- └── Pattern matching
265
- ↑
266
- @abapify/adt-playwright (this package)
267
- ├── adapter.ts - Playwright BrowserAdapter implementation
268
- ├── playwright-auth.ts - Wrapper around browser-auth
269
- ├── auth-plugin.ts - AuthManager compatibility
270
- └── index.ts - Public exports
271
- ```
272
-
273
- ## Exports
274
-
275
- ```typescript
276
- // Main auth object
277
- export { playwrightAuth, playwright } from '@abapify/adt-playwright';
278
-
279
- // Config helper
280
- export { withPlaywright } from '@abapify/adt-playwright';
281
-
282
- // Utilities
283
- export { toCookieHeader, toHeaders } from '@abapify/adt-playwright';
284
-
285
- // AuthManager plugin (default export)
286
- import authPlugin from '@abapify/adt-playwright';
287
-
288
- // Types
289
- export type {
290
- PlaywrightCredentials,
291
- PlaywrightAuthOptions,
292
- PlaywrightPluginOptions,
293
- CookieData,
294
- } from '@abapify/adt-playwright';
295
- ```
296
-
297
- ## Troubleshooting
298
-
299
- ### Browser doesn't open
300
-
301
- Ensure `headless: false` is set:
302
-
303
- ```typescript
304
- {
305
- headless: false;
306
- }
307
- ```
308
-
309
- ### Cookies not captured
310
-
311
- Specify the required cookies explicitly:
312
-
313
- ```typescript
314
- {
315
- requiredCookies: ['SAP_SESSIONID_*', 'sap-usercontext'];
316
- }
317
- ```
318
-
319
- ### SSL Certificate errors
320
-
321
- Enable `ignoreHTTPSErrors` (default is true):
322
-
323
- ```typescript
324
- {
325
- ignoreHTTPSErrors: true;
326
- }
327
- ```
26
+ ## Features
328
27
 
329
- ### Session not persisting
28
+ - Browser-based SSO login (SAML / IdP) with Playwright
29
+ - Session cookie persistence and reuse
30
+ - Drop-in wrapper for `adt.config.ts`
330
31
 
331
- Check that `userDataDir` is enabled and the directory is writable:
32
+ ## Documentation
332
33
 
333
- ```typescript
334
- {
335
- userDataDir: true;
336
- }
337
- // or
338
- {
339
- userDataDir: '/writable/path';
340
- }
341
- ```
34
+ **[adt-cli.netlify.app/sdk/packages/adt-playwright](https://adt-cli.netlify.app/sdk/packages/adt-playwright)**
342
35
 
343
- ## Related Packages
36
+ ---
344
37
 
345
- - [`@abapify/browser-auth`](../browser-auth) - Core authentication logic
346
- - [`@abapify/adt-puppeteer`](../adt-puppeteer) - Puppeteer alternative
347
- - [`@abapify/adt-auth`](../adt-auth) - Authentication manager
348
- - [`@abapify/adt-config`](../adt-config) - Configuration utilities
38
+ Part of [**abapify**](https://github.com/abapify/adt-cli) — open, typed tooling for SAP ABAP Development Tools (ADT): CLI, MCP server, and SDK.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":["BrowserCredentials","BrowserAuthOptions","BrowserAuthOptions"],"sources":["../src/playwright-auth.ts","../src/auth-plugin.ts","../src/index.ts"],"mappings":";;;KAeY,wBAAwBA;KACxB,wBAAwBC;;;;cAKvB;;;;EAKA,aAAA,SAAA,wBACR,QAAQ;;;;;;;;EAaY,QAAA;IACrB;MAAS;QAAkB,OAAO;;;MAChC,QAAQ;;cAaD;;;;EA7BA,aAAA,SAAA,wBACR,QAAQ;;;;;;;;EAaY,QAAA;IACrB;MAAS;QAAkB,OAAO;;;MAChC,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;cCkCR,YAAY;;;;KCpDN,0BAA0BC;;;;iBAetB,eACd,QAAQ,WACR,UAAU,QAAQA,wBACjB"}
1
+ {"version":3,"file":"index.d.mts","names":["BrowserCredentials","BrowserAuthOptions","BrowserAuthOptions"],"sources":["../src/playwright-auth.ts","../src/auth-plugin.ts","../src/index.ts"],"mappings":";;;KAeY,wBAAwBA;KACxB,wBAAwBC;;;;cAKvB;;;;EAIW,aAAA,SAAA,wBAAwB,QAAQ;;;;;;;;EAarC,QAAA;IACf;MAAS;QAAkB,OAAO;;;MAChC,QAAQ;;cAYD;;;;EA3BW,aAAA,SAAA,wBAAwB,QAAQ;;;;;;;;EAarC,QAAA;IACf;MAAS;QAAkB,OAAO;;;MAChC,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;cCoCR,YAAY;;;;KCpDN,0BAA0BC;;;;iBAetB,eACd,QAAQ,WACR,UAAU,QAAQA,wBACjB"}
package/dist/index.mjs CHANGED
@@ -69,10 +69,11 @@ function createPlaywrightAdapter() {
69
69
  async clearCookies(domain) {
70
70
  if (!context) throw new Error("Browser not launched");
71
71
  const toRemove = (await context.cookies()).filter((c) => c.domain.includes(domain) || domain.includes(c.domain.replace(/^\./, "")));
72
- for (const cookie of toRemove) await context.clearCookies({
72
+ const browserContext = context;
73
+ await Promise.all(toRemove.map((cookie) => browserContext.clearCookies({
73
74
  name: cookie.name,
74
75
  domain: cookie.domain
75
- });
76
+ })));
76
77
  },
77
78
  async getUserAgent() {
78
79
  if (!context) throw new Error("Browser not launched");
@@ -116,7 +117,7 @@ const playwrightAuth = {
116
117
  /**
117
118
  * Authenticate using Playwright browser
118
119
  */
119
- async authenticate(options) {
120
+ authenticate(options) {
120
121
  const adapter = createPlaywrightAdapter();
121
122
  return authenticate(adapter, options);
122
123
  },
@@ -127,9 +128,9 @@ const playwrightAuth = {
127
128
  /**
128
129
  * Refresh is not reliable with Okta SSO - always return null to trigger full re-authentication
129
130
  */
130
- async refresh(session) {
131
+ refresh(session) {
131
132
  (session?.auth?.pluginOptions?.log ?? console.log)("🔄 Session expired, will trigger full re-authentication...");
132
- return null;
133
+ return Promise.resolve(null);
133
134
  }
134
135
  };
135
136
  const playwright = playwrightAuth;
@@ -217,8 +218,8 @@ const authPlugin = {
217
218
  * @param _session - The existing session (unused)
218
219
  * @returns Always null, indicating refresh is not supported
219
220
  */
220
- async refresh(_session) {
221
- return null;
221
+ refresh(_session) {
222
+ return Promise.resolve(null);
222
223
  }
223
224
  };
224
225
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/adapter.ts","../src/playwright-auth.ts","../src/auth-plugin.ts","../src/index.ts"],"sourcesContent":["/**\n * Playwright Browser Adapter\n *\n * Implements BrowserAdapter interface for Playwright.\n * This is a thin wrapper - all auth logic is in @abapify/browser-auth.\n */\n\nimport { chromium } from 'playwright';\nimport type { BrowserContext, Page, Cookie } from 'playwright';\nimport type {\n BrowserAdapter,\n CookieData,\n ResponseEvent,\n} from '@abapify/browser-auth';\n\n/**\n * Convert Playwright cookie to CookieData\n */\nfunction convertCookie(cookie: Cookie): CookieData {\n return {\n name: cookie.name,\n value: cookie.value,\n domain: cookie.domain,\n path: cookie.path,\n expires: cookie.expires,\n httpOnly: cookie.httpOnly,\n secure: cookie.secure,\n sameSite: cookie.sameSite as CookieData['sameSite'],\n };\n}\n\n/**\n * Create a Playwright browser adapter\n */\nexport function createPlaywrightAdapter(): BrowserAdapter {\n let context: BrowserContext | null = null;\n let page: Page | null = null;\n\n const responseHandlers: ((event: ResponseEvent) => void)[] = [];\n const closeHandlers: (() => void)[] = [];\n\n return {\n async launch(options) {\n const { headless, userDataDir, ignoreHTTPSErrors, userAgent } = options;\n\n if (userDataDir) {\n // Persistent context - stores cookies/session\n context = await chromium.launchPersistentContext(userDataDir, {\n headless,\n ignoreHTTPSErrors,\n userAgent,\n });\n } else {\n const browser = await chromium.launch({ headless });\n context = await browser.newContext({ ignoreHTTPSErrors, userAgent });\n }\n },\n\n async newPage() {\n if (!context) throw new Error('Browser not launched');\n page = await context.newPage();\n\n // Wire up event handlers\n page.on('response', (response) => {\n const event: ResponseEvent = {\n url: response.url(),\n status: response.status(),\n };\n responseHandlers.forEach((handler) => handler(event));\n });\n\n page.once('close', () => {\n closeHandlers.forEach((handler) => handler());\n });\n },\n\n async goto(url, options) {\n if (!page) throw new Error('Page not created');\n await page\n .goto(url, { timeout: options?.timeout ?? 30000 })\n // Navigation errors are intentionally ignored; caller handles auth via event listeners\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n .catch(() => {});\n },\n\n async getCookies() {\n if (!context) throw new Error('Browser not launched');\n const cookies = await context.cookies();\n return cookies.map(convertCookie);\n },\n\n async clearCookies(domain: string) {\n if (!context) throw new Error('Browser not launched');\n const cookies = await context.cookies();\n const toRemove = cookies.filter(\n (c) =>\n c.domain.includes(domain) ||\n domain.includes(c.domain.replace(/^\\./, '')),\n );\n // Clear each matching cookie individually\n for (const cookie of toRemove) {\n await context.clearCookies({\n name: cookie.name,\n domain: cookie.domain,\n });\n }\n },\n\n async getUserAgent() {\n if (!context) throw new Error('Browser not launched');\n const uaPage = await context.newPage();\n const userAgent = await uaPage.evaluate(() => navigator.userAgent);\n await uaPage.close();\n return userAgent;\n },\n\n async closePage() {\n if (page) {\n await page.close();\n page = null;\n }\n },\n\n async close() {\n if (context) {\n await context.close();\n context = null;\n }\n },\n\n onResponse(handler) {\n responseHandlers.push(handler);\n },\n\n onPageClose(handler) {\n closeHandlers.push(handler);\n },\n };\n}\n","/**\n * Playwright Authentication Plugin\n *\n * Thin wrapper around @abapify/browser-auth core.\n * Provides Playwright-specific browser adapter.\n */\n\nimport { authenticate, testCredentials } from '@abapify/browser-auth';\nimport type {\n BrowserCredentials,\n BrowserAuthOptions,\n} from '@abapify/browser-auth';\nimport { createPlaywrightAdapter } from './adapter';\n\n// Re-export types with Playwright-specific names for backwards compatibility\nexport type PlaywrightCredentials = BrowserCredentials;\nexport type PlaywrightAuthOptions = BrowserAuthOptions;\n\n/**\n * Playwright authentication object\n */\nexport const playwrightAuth = {\n /**\n * Authenticate using Playwright browser\n */\n async authenticate(\n options: PlaywrightAuthOptions,\n ): Promise<PlaywrightCredentials> {\n const adapter = createPlaywrightAdapter();\n return authenticate(adapter, options);\n },\n\n /**\n * Test if credentials are still valid\n */\n test: testCredentials,\n\n /**\n * Refresh is not reliable with Okta SSO - always return null to trigger full re-authentication\n */\n async refresh(session: {\n auth?: { pluginOptions?: { log?: (message: string) => void } };\n }): Promise<PlaywrightCredentials | null> {\n const log = session?.auth?.pluginOptions?.log as\n | ((message: string) => void)\n | undefined;\n (log ?? console.log)(\n '🔄 Session expired, will trigger full re-authentication...',\n );\n return null;\n },\n};\n\n// Re-export utilities\n// Legacy export\nexport const playwright = playwrightAuth;\nexport { toCookieHeader, toHeaders } from '@abapify/browser-auth';\n","/**\n * @fileoverview Playwright Authentication Plugin for AuthManager\n *\n * This module provides the standard auth plugin interface that AuthManager expects.\n * It wraps the Playwright-based browser authentication to return credentials in\n * the format required by the ADT authentication system.\n *\n * @module @abapify/adt-playwright/auth-plugin\n */\n\nimport type {\n AuthPlugin,\n AuthPluginResult,\n AuthPluginOptions,\n AuthSession,\n} from '@abapify/adt-auth';\nimport { playwrightAuth, toCookieHeader } from './playwright-auth';\n\n/** Default session duration when cookies don't specify expiration (8 hours) */\nconst DEFAULT_SESSION_DURATION_MS = 8 * 60 * 60 * 1000;\n\n/**\n * Determines the session expiration time from cookie data.\n *\n * Examines all cookies and returns the earliest expiration time found.\n * If no cookies have expiration set (common with session cookies),\n * returns a default expiration of 8 hours from now.\n *\n * @param cookies - Array of cookie objects with optional expires field\n * @returns The earliest expiration date, or default 8 hours from now\n *\n * @example\n * // Cookie with expiration\n * getExpiresAt([{ expires: 1732900000 }]) // Returns Date from timestamp\n *\n * @example\n * // Session cookie (no expiration)\n * getExpiresAt([{ expires: 0 }]) // Returns Date 8 hours from now\n */\nfunction getExpiresAt(cookies: { expires?: number }[]): Date {\n const expirations = cookies\n .filter((c) => c.expires && c.expires > 0)\n .map((c) => c.expires! * 1000); // Cookie expires is in seconds, convert to ms\n\n if (expirations.length > 0) {\n return new Date(Math.min(...expirations));\n }\n\n return new Date(Date.now() + DEFAULT_SESSION_DURATION_MS);\n}\n\n/**\n * Playwright authentication plugin for AuthManager.\n *\n * Implements the standard AuthPlugin interface to integrate Playwright-based\n * browser authentication with the ADT authentication system.\n *\n * @remarks\n * This plugin:\n * - Opens a browser window for SSO authentication\n * - Captures session cookies after successful login\n * - Converts cookies to the format expected by AuthManager\n * - Does NOT support silent refresh (Okta SSO requires user interaction)\n *\n * @example\n * ```typescript\n * // Used internally by AuthManager when destination type is '@abapify/adt-playwright'\n * import authPlugin from '@abapify/adt-playwright';\n *\n * const result = await authPlugin.authenticate({\n * url: 'https://sap-system.example.com',\n * headless: false,\n * userDataDir: true,\n * });\n * ```\n */\nconst authPlugin: AuthPlugin = {\n /**\n * Authenticate using Playwright browser automation.\n *\n * Opens a browser window, navigates to the SAP system, and waits for\n * the user to complete SSO authentication. Captures cookies and returns\n * them in AuthPluginResult format.\n *\n * @param options - Authentication options including URL and browser settings\n * @returns Promise resolving to credentials in AuthPluginResult format\n */\n async authenticate(options: AuthPluginOptions): Promise<AuthPluginResult> {\n const credentials = await playwrightAuth.authenticate(options);\n const cookieString = toCookieHeader(credentials);\n const expiresAt = getExpiresAt(credentials.cookies);\n\n return {\n method: 'cookie',\n credentials: {\n cookies: cookieString,\n expiresAt,\n },\n };\n },\n\n /**\n * Attempt to refresh an existing session.\n *\n * @remarks\n * Always returns null because Okta SSO sessions cannot be silently refreshed.\n * When a session expires, full re-authentication with user interaction is required.\n * The AuthManager will handle this by calling authenticate() again.\n *\n * @param _session - The existing session (unused)\n * @returns Always null, indicating refresh is not supported\n */\n async refresh(_session: AuthSession): Promise<AuthPluginResult | null> {\n return null;\n },\n};\n\nexport default authPlugin;\n","/**\n * @abapify/adt-playwright\n *\n * Playwright-based SSO authentication plugin for ADT client.\n * Uses @abapify/browser-auth core with Playwright adapter.\n */\n\nimport type { AdtConfig, Destination } from '@abapify/adt-config';\nimport type { BrowserAuthOptions } from '@abapify/browser-auth';\n\n// Re-export types\nexport type {\n PlaywrightCredentials,\n PlaywrightAuthOptions,\n} from './playwright-auth';\nexport type {\n BrowserCredentials,\n BrowserAuthOptions,\n CookieData,\n} from '@abapify/browser-auth';\n\n/**\n * Plugin-level options applied to all destinations\n */\nexport type PlaywrightPluginOptions = BrowserAuthOptions;\n\n/**\n * Create a playwright destination config\n */\nfunction createPlaywrightDestination(options: BrowserAuthOptions): Destination {\n return {\n type: '@abapify/adt-playwright',\n options,\n };\n}\n\n/**\n * Wrap a standard config with playwright auth for all destinations.\n */\nexport function withPlaywright(\n config: AdtConfig,\n options?: Partial<BrowserAuthOptions>,\n): AdtConfig {\n if (!config.destinations) {\n return config;\n }\n\n const destinations: Record<string, Destination> = {};\n\n for (const [name, dest] of Object.entries(config.destinations)) {\n if (typeof dest === 'object' && 'type' in dest) {\n if (\n dest.type === '@abapify/adt-playwright' ||\n dest.type === 'playwright'\n ) {\n destinations[name] = {\n type: '@abapify/adt-playwright',\n options: { ...options, ...(dest.options as BrowserAuthOptions) },\n };\n } else {\n destinations[name] = dest;\n }\n } else if (typeof dest === 'string') {\n destinations[name] = createPlaywrightDestination({\n url: dest,\n ...options,\n });\n } else {\n // Destination-specific options override global options\n destinations[name] = createPlaywrightDestination({\n ...options,\n ...(dest as BrowserAuthOptions),\n });\n }\n }\n\n return { ...config, destinations };\n}\n\n// Main exports\nexport {\n playwrightAuth,\n playwright,\n toCookieHeader,\n toHeaders,\n} from './playwright-auth';\n\n// AuthManager compatibility exports\nexport { default } from './auth-plugin';\nexport { default as authPlugin } from './auth-plugin';\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/adapter.ts","../src/playwright-auth.ts","../src/auth-plugin.ts","../src/index.ts"],"sourcesContent":["/**\n * Playwright Browser Adapter\n *\n * Implements BrowserAdapter interface for Playwright.\n * This is a thin wrapper - all auth logic is in @abapify/browser-auth.\n */\n\nimport { chromium } from 'playwright';\nimport type { BrowserContext, Page, Cookie } from 'playwright';\nimport type {\n BrowserAdapter,\n CookieData,\n ResponseEvent,\n} from '@abapify/browser-auth';\n\n/**\n * Convert Playwright cookie to CookieData\n */\nfunction convertCookie(cookie: Cookie): CookieData {\n return {\n name: cookie.name,\n value: cookie.value,\n domain: cookie.domain,\n path: cookie.path,\n expires: cookie.expires,\n httpOnly: cookie.httpOnly,\n secure: cookie.secure,\n sameSite: cookie.sameSite as CookieData['sameSite'],\n };\n}\n\n/**\n * Create a Playwright browser adapter\n */\nexport function createPlaywrightAdapter(): BrowserAdapter {\n let context: BrowserContext | null = null;\n let page: Page | null = null;\n\n const responseHandlers: ((event: ResponseEvent) => void)[] = [];\n const closeHandlers: (() => void)[] = [];\n\n return {\n async launch(options) {\n const { headless, userDataDir, ignoreHTTPSErrors, userAgent } = options;\n\n if (userDataDir) {\n // Persistent context - stores cookies/session\n context = await chromium.launchPersistentContext(userDataDir, {\n headless,\n ignoreHTTPSErrors,\n userAgent,\n });\n } else {\n const browser = await chromium.launch({ headless });\n context = await browser.newContext({ ignoreHTTPSErrors, userAgent });\n }\n },\n\n async newPage() {\n if (!context) throw new Error('Browser not launched');\n page = await context.newPage();\n\n // Wire up event handlers\n page.on('response', (response) => {\n const event: ResponseEvent = {\n url: response.url(),\n status: response.status(),\n };\n responseHandlers.forEach((handler) => handler(event));\n });\n\n page.once('close', () => {\n closeHandlers.forEach((handler) => handler());\n });\n },\n\n async goto(url, options) {\n if (!page) throw new Error('Page not created');\n await page\n .goto(url, { timeout: options?.timeout ?? 30000 })\n // Navigation errors are intentionally ignored; caller handles auth via event listeners\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n .catch(() => {});\n },\n\n async getCookies() {\n if (!context) throw new Error('Browser not launched');\n const cookies = await context.cookies();\n return cookies.map(convertCookie);\n },\n\n async clearCookies(domain: string) {\n if (!context) throw new Error('Browser not launched');\n const cookies = await context.cookies();\n const toRemove = cookies.filter(\n (c) =>\n c.domain.includes(domain) ||\n domain.includes(c.domain.replace(/^\\./, '')),\n );\n // Clear each matching cookie individually\n const browserContext = context;\n await Promise.all(\n toRemove.map((cookie) =>\n browserContext.clearCookies({\n name: cookie.name,\n domain: cookie.domain,\n }),\n ),\n );\n },\n\n async getUserAgent() {\n if (!context) throw new Error('Browser not launched');\n const uaPage = await context.newPage();\n const userAgent = await uaPage.evaluate(() => navigator.userAgent);\n await uaPage.close();\n return userAgent;\n },\n\n async closePage() {\n if (page) {\n await page.close();\n page = null;\n }\n },\n\n async close() {\n if (context) {\n await context.close();\n context = null;\n }\n },\n\n onResponse(handler) {\n responseHandlers.push(handler);\n },\n\n onPageClose(handler) {\n closeHandlers.push(handler);\n },\n };\n}\n","/**\n * Playwright Authentication Plugin\n *\n * Thin wrapper around @abapify/browser-auth core.\n * Provides Playwright-specific browser adapter.\n */\n\nimport { authenticate, testCredentials } from '@abapify/browser-auth';\nimport type {\n BrowserCredentials,\n BrowserAuthOptions,\n} from '@abapify/browser-auth';\nimport { createPlaywrightAdapter } from './adapter';\n\n// Re-export types with Playwright-specific names for backwards compatibility\nexport type PlaywrightCredentials = BrowserCredentials;\nexport type PlaywrightAuthOptions = BrowserAuthOptions;\n\n/**\n * Playwright authentication object\n */\nexport const playwrightAuth = {\n /**\n * Authenticate using Playwright browser\n */\n authenticate(options: PlaywrightAuthOptions): Promise<PlaywrightCredentials> {\n const adapter = createPlaywrightAdapter();\n return authenticate(adapter, options);\n },\n\n /**\n * Test if credentials are still valid\n */\n test: testCredentials,\n\n /**\n * Refresh is not reliable with Okta SSO - always return null to trigger full re-authentication\n */\n refresh(session: {\n auth?: { pluginOptions?: { log?: (message: string) => void } };\n }): Promise<PlaywrightCredentials | null> {\n const log = session?.auth?.pluginOptions?.log as\n ((message: string) => void) | undefined;\n (log ?? console.log)(\n '🔄 Session expired, will trigger full re-authentication...',\n );\n return Promise.resolve(null);\n },\n};\n\n// Re-export utilities\n// Legacy export\nexport const playwright = playwrightAuth;\nexport { toCookieHeader, toHeaders } from '@abapify/browser-auth';\n","/**\n * @fileoverview Playwright Authentication Plugin for AuthManager\n *\n * This module provides the standard auth plugin interface that AuthManager expects.\n * It wraps the Playwright-based browser authentication to return credentials in\n * the format required by the ADT authentication system.\n *\n * @module @abapify/adt-playwright/auth-plugin\n */\n\nimport type {\n AuthPlugin,\n AuthPluginResult,\n AuthPluginOptions,\n AuthSession,\n} from '@abapify/adt-auth';\nimport { playwrightAuth, toCookieHeader } from './playwright-auth';\n\n/** Default session duration when cookies don't specify expiration (8 hours) */\nconst DEFAULT_SESSION_DURATION_MS = 8 * 60 * 60 * 1000;\n\n/**\n * Determines the session expiration time from cookie data.\n *\n * Examines all cookies and returns the earliest expiration time found.\n * If no cookies have expiration set (common with session cookies),\n * returns a default expiration of 8 hours from now.\n *\n * @param cookies - Array of cookie objects with optional expires field\n * @returns The earliest expiration date, or default 8 hours from now\n *\n * @example\n * // Cookie with expiration\n * getExpiresAt([{ expires: 1732900000 }]) // Returns Date from timestamp\n *\n * @example\n * // Session cookie (no expiration)\n * getExpiresAt([{ expires: 0 }]) // Returns Date 8 hours from now\n */\nfunction getExpiresAt(cookies: { expires?: number }[]): Date {\n const expirations = cookies\n .filter((c) => c.expires && c.expires > 0)\n .map((c) => c.expires! * 1000); // Cookie expires is in seconds, convert to ms\n\n if (expirations.length > 0) {\n return new Date(Math.min(...expirations));\n }\n\n return new Date(Date.now() + DEFAULT_SESSION_DURATION_MS);\n}\n\n/**\n * Playwright authentication plugin for AuthManager.\n *\n * Implements the standard AuthPlugin interface to integrate Playwright-based\n * browser authentication with the ADT authentication system.\n *\n * @remarks\n * This plugin:\n * - Opens a browser window for SSO authentication\n * - Captures session cookies after successful login\n * - Converts cookies to the format expected by AuthManager\n * - Does NOT support silent refresh (Okta SSO requires user interaction)\n *\n * @example\n * ```typescript\n * // Used internally by AuthManager when destination type is '@abapify/adt-playwright'\n * import authPlugin from '@abapify/adt-playwright';\n *\n * const result = await authPlugin.authenticate({\n * url: 'https://sap-system.example.com',\n * headless: false,\n * userDataDir: true,\n * });\n * ```\n */\nconst authPlugin: AuthPlugin = {\n /**\n * Authenticate using Playwright browser automation.\n *\n * Opens a browser window, navigates to the SAP system, and waits for\n * the user to complete SSO authentication. Captures cookies and returns\n * them in AuthPluginResult format.\n *\n * @param options - Authentication options including URL and browser settings\n * @returns Promise resolving to credentials in AuthPluginResult format\n */\n async authenticate(options: AuthPluginOptions): Promise<AuthPluginResult> {\n const credentials = await playwrightAuth.authenticate(options);\n const cookieString = toCookieHeader(credentials);\n const expiresAt = getExpiresAt(credentials.cookies);\n\n return {\n method: 'cookie',\n credentials: {\n cookies: cookieString,\n expiresAt,\n },\n };\n },\n\n /**\n * Attempt to refresh an existing session.\n *\n * @remarks\n * Always returns null because Okta SSO sessions cannot be silently refreshed.\n * When a session expires, full re-authentication with user interaction is required.\n * The AuthManager will handle this by calling authenticate() again.\n *\n * @param _session - The existing session (unused)\n * @returns Always null, indicating refresh is not supported\n */\n refresh(_session: AuthSession): Promise<AuthPluginResult | null> {\n return Promise.resolve(null);\n },\n};\n\nexport default authPlugin;\n","/**\n * @abapify/adt-playwright\n *\n * Playwright-based SSO authentication plugin for ADT client.\n * Uses @abapify/browser-auth core with Playwright adapter.\n */\n\nimport type { AdtConfig, Destination } from '@abapify/adt-config';\nimport type { BrowserAuthOptions } from '@abapify/browser-auth';\n\n// Re-export types\nexport type {\n PlaywrightCredentials,\n PlaywrightAuthOptions,\n} from './playwright-auth';\nexport type {\n BrowserCredentials,\n BrowserAuthOptions,\n CookieData,\n} from '@abapify/browser-auth';\n\n/**\n * Plugin-level options applied to all destinations\n */\nexport type PlaywrightPluginOptions = BrowserAuthOptions;\n\n/**\n * Create a playwright destination config\n */\nfunction createPlaywrightDestination(options: BrowserAuthOptions): Destination {\n return {\n type: '@abapify/adt-playwright',\n options,\n };\n}\n\n/**\n * Wrap a standard config with playwright auth for all destinations.\n */\nexport function withPlaywright(\n config: AdtConfig,\n options?: Partial<BrowserAuthOptions>,\n): AdtConfig {\n if (!config.destinations) {\n return config;\n }\n\n const destinations: Record<string, Destination> = {};\n\n for (const [name, dest] of Object.entries(config.destinations)) {\n if (typeof dest === 'object' && 'type' in dest) {\n if (\n dest.type === '@abapify/adt-playwright' ||\n dest.type === 'playwright'\n ) {\n destinations[name] = {\n type: '@abapify/adt-playwright',\n options: { ...options, ...(dest.options as BrowserAuthOptions) },\n };\n } else {\n destinations[name] = dest;\n }\n } else if (typeof dest === 'string') {\n destinations[name] = createPlaywrightDestination({\n url: dest,\n ...options,\n });\n } else {\n // Destination-specific options override global options\n destinations[name] = createPlaywrightDestination({\n ...options,\n ...(dest as BrowserAuthOptions),\n });\n }\n }\n\n return { ...config, destinations };\n}\n\n// Main exports\nexport {\n playwrightAuth,\n playwright,\n toCookieHeader,\n toHeaders,\n} from './playwright-auth';\n\n// AuthManager compatibility exports\nexport { default } from './auth-plugin';\nexport { default as authPlugin } from './auth-plugin';\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abapify/adt-playwright",
3
- "version": "0.4.33",
3
+ "version": "0.4.36",
4
4
  "description": "Playwright-based SSO authentication plugin for ADT client",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -17,9 +17,9 @@
17
17
  "README.md"
18
18
  ],
19
19
  "dependencies": {
20
- "@abapify/adt-auth": "0.4.33",
21
- "@abapify/adt-config": "0.4.33",
22
- "@abapify/browser-auth": "0.4.33",
20
+ "@abapify/adt-auth": "0.4.36",
21
+ "@abapify/adt-config": "0.4.36",
22
+ "@abapify/browser-auth": "0.4.36",
23
23
  "playwright": "^1.57.0"
24
24
  },
25
25
  "devDependencies": {