mirror of
https://github.com/microsoft/playwright.git
synced 2024-11-24 14:55:38 +03:00
feat(client-certificates): allow passing certificates from memory (#32210)
This commit is contained in:
parent
74f5ce5489
commit
010778f6c5
@ -531,15 +531,18 @@ Does not enforce fixed viewport, allows resizing window in the headed mode.
|
||||
- `clientCertificates` <[Array]<[Object]>>
|
||||
- `origin` <[string]> Exact origin that the certificate is valid for. Origin includes `https` protocol, a hostname and optionally a port.
|
||||
- `certPath` ?<[path]> Path to the file with the certificate in PEM format.
|
||||
- `cert` ?<[Buffer]> Direct value of the certificate in PEM format.
|
||||
- `keyPath` ?<[path]> Path to the file with the private key in PEM format.
|
||||
- `key` ?<[Buffer]> Direct value of the private key in PEM format.
|
||||
- `pfxPath` ?<[path]> Path to the PFX or PKCS12 encoded private key and certificate chain.
|
||||
- `pfx` ?<[Buffer]> Direct value of the PFX or PKCS12 encoded private key and certificate chain.
|
||||
- `passphrase` ?<[string]> Passphrase for the private key (PEM or PFX).
|
||||
|
||||
TLS Client Authentication allows the server to request a client certificate and verify it.
|
||||
|
||||
**Details**
|
||||
|
||||
An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the certficiate is encrypted. The `origin` property should be provided with an exact match to the request origin that the certificate is valid for.
|
||||
An array of client certificates to be used. Each certificate object must have either both `certPath` and `keyPath`, a single `pfxPath`, or their corresponding direct value equivalents (`cert` and `key`, or `pfx`). Optionally, `passphrase` property should be provided if the certificate is encrypted. The `origin` property should be provided with an exact match to the request origin that the certificate is valid for.
|
||||
|
||||
:::note
|
||||
Using Client Certificates in combination with Proxy Servers is not supported.
|
||||
|
@ -552,13 +552,19 @@ function toAcceptDownloadsProtocol(acceptDownloads?: boolean) {
|
||||
export async function toClientCertificatesProtocol(certs?: BrowserContextOptions['clientCertificates']): Promise<channels.PlaywrightNewRequestParams['clientCertificates']> {
|
||||
if (!certs)
|
||||
return undefined;
|
||||
return await Promise.all(certs.map(async cert => {
|
||||
return {
|
||||
origin: cert.origin,
|
||||
cert: cert.certPath ? await fs.promises.readFile(cert.certPath) : undefined,
|
||||
key: cert.keyPath ? await fs.promises.readFile(cert.keyPath) : undefined,
|
||||
pfx: cert.pfxPath ? await fs.promises.readFile(cert.pfxPath) : undefined,
|
||||
passphrase: cert.passphrase,
|
||||
|
||||
const bufferizeContent = async (value?: Buffer, path?: string): Promise<Buffer | undefined> => {
|
||||
if (value)
|
||||
return value;
|
||||
if (path)
|
||||
return await fs.promises.readFile(path);
|
||||
};
|
||||
}));
|
||||
|
||||
return await Promise.all(certs.map(async cert => ({
|
||||
origin: cert.origin,
|
||||
cert: await bufferizeContent(cert.cert, cert.certPath),
|
||||
key: await bufferizeContent(cert.key, cert.keyPath),
|
||||
pfx: await bufferizeContent(cert.pfx, cert.pfxPath),
|
||||
passphrase: cert.passphrase,
|
||||
})));
|
||||
}
|
||||
|
@ -49,8 +49,11 @@ export const kLifecycleEvents: Set<LifecycleEvent> = new Set(['load', 'domconten
|
||||
|
||||
export type ClientCertificate = {
|
||||
origin: string;
|
||||
cert?: Buffer;
|
||||
certPath?: string;
|
||||
key?: Buffer;
|
||||
keyPath?: string;
|
||||
pfx?: Buffer;
|
||||
pfxPath?: string;
|
||||
passphrase?: string;
|
||||
};
|
||||
|
92
packages/playwright-core/types/types.d.ts
vendored
92
packages/playwright-core/types/types.d.ts
vendored
@ -9138,10 +9138,10 @@ export interface Browser {
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a
|
||||
* single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the
|
||||
* certficiate is encrypted. The `origin` property should be provided with an exact match to the request origin that
|
||||
* the certificate is valid for.
|
||||
* An array of client certificates to be used. Each certificate object must have either both `certPath` and `keyPath`,
|
||||
* a single `pfxPath`, or their corresponding direct value equivalents (`cert` and `key`, or `pfx`). Optionally,
|
||||
* `passphrase` property should be provided if the certificate is encrypted. The `origin` property should be provided
|
||||
* with an exact match to the request origin that the certificate is valid for.
|
||||
*
|
||||
* **NOTE** Using Client Certificates in combination with Proxy Servers is not supported.
|
||||
*
|
||||
@ -9159,16 +9159,31 @@ export interface Browser {
|
||||
*/
|
||||
certPath?: string;
|
||||
|
||||
/**
|
||||
* Direct value of the certificate in PEM format.
|
||||
*/
|
||||
cert?: Buffer;
|
||||
|
||||
/**
|
||||
* Path to the file with the private key in PEM format.
|
||||
*/
|
||||
keyPath?: string;
|
||||
|
||||
/**
|
||||
* Direct value of the private key in PEM format.
|
||||
*/
|
||||
key?: Buffer;
|
||||
|
||||
/**
|
||||
* Path to the PFX or PKCS12 encoded private key and certificate chain.
|
||||
*/
|
||||
pfxPath?: string;
|
||||
|
||||
/**
|
||||
* Direct value of the PFX or PKCS12 encoded private key and certificate chain.
|
||||
*/
|
||||
pfx?: Buffer;
|
||||
|
||||
/**
|
||||
* Passphrase for the private key (PEM or PFX).
|
||||
*/
|
||||
@ -13850,10 +13865,10 @@ export interface BrowserType<Unused = {}> {
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a
|
||||
* single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the
|
||||
* certficiate is encrypted. The `origin` property should be provided with an exact match to the request origin that
|
||||
* the certificate is valid for.
|
||||
* An array of client certificates to be used. Each certificate object must have either both `certPath` and `keyPath`,
|
||||
* a single `pfxPath`, or their corresponding direct value equivalents (`cert` and `key`, or `pfx`). Optionally,
|
||||
* `passphrase` property should be provided if the certificate is encrypted. The `origin` property should be provided
|
||||
* with an exact match to the request origin that the certificate is valid for.
|
||||
*
|
||||
* **NOTE** Using Client Certificates in combination with Proxy Servers is not supported.
|
||||
*
|
||||
@ -13871,16 +13886,31 @@ export interface BrowserType<Unused = {}> {
|
||||
*/
|
||||
certPath?: string;
|
||||
|
||||
/**
|
||||
* Direct value of the certificate in PEM format.
|
||||
*/
|
||||
cert?: Buffer;
|
||||
|
||||
/**
|
||||
* Path to the file with the private key in PEM format.
|
||||
*/
|
||||
keyPath?: string;
|
||||
|
||||
/**
|
||||
* Direct value of the private key in PEM format.
|
||||
*/
|
||||
key?: Buffer;
|
||||
|
||||
/**
|
||||
* Path to the PFX or PKCS12 encoded private key and certificate chain.
|
||||
*/
|
||||
pfxPath?: string;
|
||||
|
||||
/**
|
||||
* Direct value of the PFX or PKCS12 encoded private key and certificate chain.
|
||||
*/
|
||||
pfx?: Buffer;
|
||||
|
||||
/**
|
||||
* Passphrase for the private key (PEM or PFX).
|
||||
*/
|
||||
@ -16259,10 +16289,10 @@ export interface APIRequest {
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a
|
||||
* single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the
|
||||
* certficiate is encrypted. The `origin` property should be provided with an exact match to the request origin that
|
||||
* the certificate is valid for.
|
||||
* An array of client certificates to be used. Each certificate object must have either both `certPath` and `keyPath`,
|
||||
* a single `pfxPath`, or their corresponding direct value equivalents (`cert` and `key`, or `pfx`). Optionally,
|
||||
* `passphrase` property should be provided if the certificate is encrypted. The `origin` property should be provided
|
||||
* with an exact match to the request origin that the certificate is valid for.
|
||||
*
|
||||
* **NOTE** Using Client Certificates in combination with Proxy Servers is not supported.
|
||||
*
|
||||
@ -16280,16 +16310,31 @@ export interface APIRequest {
|
||||
*/
|
||||
certPath?: string;
|
||||
|
||||
/**
|
||||
* Direct value of the certificate in PEM format.
|
||||
*/
|
||||
cert?: Buffer;
|
||||
|
||||
/**
|
||||
* Path to the file with the private key in PEM format.
|
||||
*/
|
||||
keyPath?: string;
|
||||
|
||||
/**
|
||||
* Direct value of the private key in PEM format.
|
||||
*/
|
||||
key?: Buffer;
|
||||
|
||||
/**
|
||||
* Path to the PFX or PKCS12 encoded private key and certificate chain.
|
||||
*/
|
||||
pfxPath?: string;
|
||||
|
||||
/**
|
||||
* Direct value of the PFX or PKCS12 encoded private key and certificate chain.
|
||||
*/
|
||||
pfx?: Buffer;
|
||||
|
||||
/**
|
||||
* Passphrase for the private key (PEM or PFX).
|
||||
*/
|
||||
@ -20600,10 +20645,10 @@ export interface BrowserContextOptions {
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a
|
||||
* single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the
|
||||
* certficiate is encrypted. The `origin` property should be provided with an exact match to the request origin that
|
||||
* the certificate is valid for.
|
||||
* An array of client certificates to be used. Each certificate object must have either both `certPath` and `keyPath`,
|
||||
* a single `pfxPath`, or their corresponding direct value equivalents (`cert` and `key`, or `pfx`). Optionally,
|
||||
* `passphrase` property should be provided if the certificate is encrypted. The `origin` property should be provided
|
||||
* with an exact match to the request origin that the certificate is valid for.
|
||||
*
|
||||
* **NOTE** Using Client Certificates in combination with Proxy Servers is not supported.
|
||||
*
|
||||
@ -20621,16 +20666,31 @@ export interface BrowserContextOptions {
|
||||
*/
|
||||
certPath?: string;
|
||||
|
||||
/**
|
||||
* Direct value of the certificate in PEM format.
|
||||
*/
|
||||
cert?: Buffer;
|
||||
|
||||
/**
|
||||
* Path to the file with the private key in PEM format.
|
||||
*/
|
||||
keyPath?: string;
|
||||
|
||||
/**
|
||||
* Direct value of the private key in PEM format.
|
||||
*/
|
||||
key?: Buffer;
|
||||
|
||||
/**
|
||||
* Path to the PFX or PKCS12 encoded private key and certificate chain.
|
||||
*/
|
||||
pfxPath?: string;
|
||||
|
||||
/**
|
||||
* Direct value of the PFX or PKCS12 encoded private key and certificate chain.
|
||||
*/
|
||||
pfx?: Buffer;
|
||||
|
||||
/**
|
||||
* Passphrase for the private key (PEM or PFX).
|
||||
*/
|
||||
|
8
packages/playwright/types/test.d.ts
vendored
8
packages/playwright/types/test.d.ts
vendored
@ -5206,10 +5206,10 @@ export interface PlaywrightTestOptions {
|
||||
*
|
||||
* **Details**
|
||||
*
|
||||
* An array of client certificates to be used. Each certificate object must have both `certPath` and `keyPath` or a
|
||||
* single `pfxPath` to load the client certificate. Optionally, `passphrase` property should be provided if the
|
||||
* certficiate is encrypted. The `origin` property should be provided with an exact match to the request origin that
|
||||
* the certificate is valid for.
|
||||
* An array of client certificates to be used. Each certificate object must have either both `certPath` and `keyPath`,
|
||||
* a single `pfxPath`, or their corresponding direct value equivalents (`cert` and `key`, or `pfx`). Optionally,
|
||||
* `passphrase` property should be provided if the certificate is encrypted. The `origin` property should be provided
|
||||
* with an exact match to the request origin that the certificate is valid for.
|
||||
*
|
||||
* **NOTE** Using Client Certificates in combination with Proxy Servers is not supported.
|
||||
*
|
||||
|
@ -303,6 +303,21 @@ test.describe('browser', () => {
|
||||
await page.close();
|
||||
});
|
||||
|
||||
test('should pass with matching certificates when passing as content', async ({ browser, startCCServer, asset, browserName }) => {
|
||||
const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && process.platform === 'darwin' });
|
||||
const page = await browser.newPage({
|
||||
ignoreHTTPSErrors: true,
|
||||
clientCertificates: [{
|
||||
origin: new URL(serverURL).origin,
|
||||
cert: await fs.promises.readFile(asset('client-certificates/client/trusted/cert.pem')),
|
||||
key: await fs.promises.readFile(asset('client-certificates/client/trusted/key.pem')),
|
||||
}],
|
||||
});
|
||||
await page.goto(serverURL);
|
||||
await expect(page.getByTestId('message')).toHaveText('Hello Alice, your certificate was issued by localhost!');
|
||||
await page.close();
|
||||
});
|
||||
|
||||
test('should not hang on tls errors during TLS 1.2 handshake', async ({ browser, asset, platform, browserName }) => {
|
||||
for (const tlsVersion of ['TLSv1.3', 'TLSv1.2'] as const) {
|
||||
await test.step(`TLS version: ${tlsVersion}`, async () => {
|
||||
@ -360,6 +375,21 @@ test.describe('browser', () => {
|
||||
await page.close();
|
||||
});
|
||||
|
||||
test('should pass with matching certificates in pfx format when passing as content', async ({ browser, startCCServer, asset, browserName }) => {
|
||||
const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && process.platform === 'darwin' });
|
||||
const page = await browser.newPage({
|
||||
ignoreHTTPSErrors: true,
|
||||
clientCertificates: [{
|
||||
origin: new URL(serverURL).origin,
|
||||
pfx: await fs.promises.readFile(asset('client-certificates/client/trusted/cert.pfx')),
|
||||
passphrase: 'secure'
|
||||
}],
|
||||
});
|
||||
await page.goto(serverURL);
|
||||
await expect(page.getByTestId('message')).toHaveText('Hello Alice, your certificate was issued by localhost!');
|
||||
await page.close();
|
||||
});
|
||||
|
||||
test('should fail with matching certificates in legacy pfx format', async ({ browser, startCCServer, asset, browserName }) => {
|
||||
const serverURL = await startCCServer({ useFakeLocalhost: browserName === 'webkit' && process.platform === 'darwin' });
|
||||
await expect(browser.newPage({
|
||||
|
Loading…
Reference in New Issue
Block a user