@polyguard/sdk 1.5.0 → 1.5.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/LICENSE +200 -0
- package/README.md +328 -0
- package/package.json +7 -3
- package/coverage/base.css +0 -224
- package/coverage/block-navigation.js +0 -87
- package/coverage/clover.xml +0 -268
- package/coverage/coverage-final.json +0 -8
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +0 -131
- package/coverage/prettify.css +0 -1
- package/coverage/prettify.js +0 -2
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +0 -210
- package/coverage/src/PolyguardClient.js.html +0 -160
- package/coverage/src/PolyguardWebsocketClientImpl.js.html +0 -634
- package/coverage/src/__tests__/helpers/fixtures.js.html +0 -166
- package/coverage/src/__tests__/helpers/index.html +0 -131
- package/coverage/src/__tests__/helpers/mockWebSocket.js.html +0 -283
- package/coverage/src/index.html +0 -176
- package/coverage/src/messageHandler.js.html +0 -448
- package/coverage/src/ticketService.js.html +0 -157
- package/coverage/src/ui.js.html +0 -349
- package/dist/sdk.global.js +0 -11256
- package/scripts/regenerate-client.sh +0 -59
- package/src/PolyguardClient.js +0 -25
- package/src/PolyguardWebsocketClientImpl.js +0 -198
- package/src/__tests__/PolyguardClient.test.js +0 -65
- package/src/__tests__/PolyguardWebsocketClientImpl.test.js +0 -617
- package/src/__tests__/helpers/fixtures.js +0 -27
- package/src/__tests__/helpers/mockWebSocket.js +0 -66
- package/src/__tests__/server.test.js +0 -148
- package/src/__tests__/sidebar.test.js +0 -289
- package/src/browser.js +0 -9
- package/src/generated/.babelrc +0 -33
- package/src/generated/.openapi-generator/FILES +0 -63
- package/src/generated/.openapi-generator/VERSION +0 -1
- package/src/generated/.openapi-generator-ignore +0 -23
- package/src/generated/.travis.yml +0 -5
- package/src/generated/README.md +0 -211
- package/src/generated/docs/ApiControllersPslStirCallRequest.md +0 -18
- package/src/generated/docs/ApiModelsApiCallModelsCallRequest.md +0 -12
- package/src/generated/docs/AppId.md +0 -8
- package/src/generated/docs/AppleApi.md +0 -88
- package/src/generated/docs/AuthApi.md +0 -1464
- package/src/generated/docs/BlockingApi.md +0 -208
- package/src/generated/docs/CallsApi.md +0 -140
- package/src/generated/docs/Certainty.md +0 -8
- package/src/generated/docs/CreateLinkRequest.md +0 -12
- package/src/generated/docs/DefaultApi.md +0 -128
- package/src/generated/docs/HTTPValidationError.md +0 -9
- package/src/generated/docs/InviteRequestModel.md +0 -10
- package/src/generated/docs/JWTRequest.md +0 -11
- package/src/generated/docs/LinksApi.md +0 -162
- package/src/generated/docs/NumberVerification.md +0 -10
- package/src/generated/docs/SdkApi.md +0 -54
- package/src/generated/docs/SecureLinksApi.md +0 -614
- package/src/generated/docs/StartAttestationRequest.md +0 -9
- package/src/generated/docs/StartMeetingRequest.md +0 -9
- package/src/generated/docs/StirApi.md +0 -52
- package/src/generated/docs/TwilioApi.md +0 -138
- package/src/generated/docs/UsersApi.md +0 -362
- package/src/generated/docs/ValidationError.md +0 -11
- package/src/generated/docs/ValidationErrorLocInner.md +0 -8
- package/src/generated/docs/VeriffApi.md +0 -188
- package/src/generated/docs/VeriffSessionRequest.md +0 -10
- package/src/generated/docs/VerifyRequest.md +0 -10
- package/src/generated/docs/WellKnownApi.md +0 -128
- package/src/generated/docs/ZoomApi.md +0 -848
- package/src/generated/git_push.sh +0 -57
- package/src/generated/mocha.opts +0 -1
- package/src/generated/package.json +0 -46
- package/src/generated/src/ApiClient.js +0 -677
- package/src/generated/src/api/AppleApi.js +0 -109
- package/src/generated/src/api/AuthApi.js +0 -1512
- package/src/generated/src/api/BlockingApi.js +0 -217
- package/src/generated/src/api/CallsApi.js +0 -164
- package/src/generated/src/api/DefaultApi.js +0 -145
- package/src/generated/src/api/LinksApi.js +0 -195
- package/src/generated/src/api/SdkApi.js +0 -81
- package/src/generated/src/api/SecureLinksApi.js +0 -670
- package/src/generated/src/api/StirApi.js +0 -80
- package/src/generated/src/api/TwilioApi.js +0 -158
- package/src/generated/src/api/UsersApi.js +0 -375
- package/src/generated/src/api/VeriffApi.js +0 -209
- package/src/generated/src/api/WellKnownApi.js +0 -145
- package/src/generated/src/api/ZoomApi.js +0 -823
- package/src/generated/src/index.js +0 -244
- package/src/generated/src/model/ApiControllersPslStirCallRequest.js +0 -211
- package/src/generated/src/model/ApiModelsApiCallModelsCallRequest.js +0 -119
- package/src/generated/src/model/CreateLinkRequest.js +0 -131
- package/src/generated/src/model/HTTPValidationError.js +0 -94
- package/src/generated/src/model/InviteRequestModel.js +0 -109
- package/src/generated/src/model/JWTRequest.js +0 -113
- package/src/generated/src/model/NumberVerification.js +0 -107
- package/src/generated/src/model/StartAttestationRequest.js +0 -95
- package/src/generated/src/model/StartMeetingRequest.js +0 -95
- package/src/generated/src/model/ValidationError.js +0 -130
- package/src/generated/src/model/VeriffSessionRequest.js +0 -107
- package/src/generated/src/model/VerifyRequest.js +0 -109
- package/src/generated/test/api/AppleApi.spec.js +0 -73
- package/src/generated/test/api/AuthApi.spec.js +0 -353
- package/src/generated/test/api/BlockingApi.spec.js +0 -103
- package/src/generated/test/api/CallsApi.spec.js +0 -83
- package/src/generated/test/api/DefaultApi.spec.js +0 -73
- package/src/generated/test/api/LinksApi.spec.js +0 -83
- package/src/generated/test/api/SdkApi.spec.js +0 -63
- package/src/generated/test/api/SecureLinksApi.spec.js +0 -143
- package/src/generated/test/api/StirApi.spec.js +0 -63
- package/src/generated/test/api/TwilioApi.spec.js +0 -83
- package/src/generated/test/api/UsersApi.spec.js +0 -133
- package/src/generated/test/api/VeriffApi.spec.js +0 -93
- package/src/generated/test/api/WellKnownApi.spec.js +0 -83
- package/src/generated/test/api/ZoomApi.spec.js +0 -213
- package/src/generated/test/model/ApiControllersPslStirCallRequest.spec.js +0 -119
- package/src/generated/test/model/ApiModelsApiCallModelsCallRequest.spec.js +0 -83
- package/src/generated/test/model/AppId.spec.js +0 -59
- package/src/generated/test/model/Certainty.spec.js +0 -59
- package/src/generated/test/model/CreateLinkRequest.spec.js +0 -83
- package/src/generated/test/model/HTTPValidationError.spec.js +0 -65
- package/src/generated/test/model/InviteRequestModel.spec.js +0 -71
- package/src/generated/test/model/JWTRequest.spec.js +0 -77
- package/src/generated/test/model/NumberVerification.spec.js +0 -71
- package/src/generated/test/model/StartAttestationRequest.spec.js +0 -65
- package/src/generated/test/model/StartMeetingRequest.spec.js +0 -65
- package/src/generated/test/model/ValidationError.spec.js +0 -77
- package/src/generated/test/model/ValidationErrorLocInner.spec.js +0 -59
- package/src/generated/test/model/VeriffSessionRequest.spec.js +0 -71
- package/src/generated/test/model/VerifyRequest.spec.js +0 -71
- package/src/index.js +0 -16
- package/src/messageHandler.js +0 -121
- package/src/server.js +0 -91
- package/src/ticketService.js +0 -28
- package/src/ui.js +0 -88
- package/vitest.config.js +0 -10
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* FastAPI
|
|
3
|
-
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
|
4
|
-
*
|
|
5
|
-
* The version of the OpenAPI document: 0.1.0
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
|
9
|
-
* https://openapi-generator.tech
|
|
10
|
-
* Do not edit the class manually.
|
|
11
|
-
*
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
(function(root, factory) {
|
|
15
|
-
if (typeof define === 'function' && define.amd) {
|
|
16
|
-
// AMD.
|
|
17
|
-
define(['expect.js', process.cwd()+'/src/index'], factory);
|
|
18
|
-
} else if (typeof module === 'object' && module.exports) {
|
|
19
|
-
// CommonJS-like environments that support module.exports, like Node.
|
|
20
|
-
factory(require('expect.js'), require(process.cwd()+'/src/index'));
|
|
21
|
-
} else {
|
|
22
|
-
// Browser globals (root is window)
|
|
23
|
-
factory(root.expect, root.FastApi);
|
|
24
|
-
}
|
|
25
|
-
}(this, function(expect, FastApi) {
|
|
26
|
-
'use strict';
|
|
27
|
-
|
|
28
|
-
var instance;
|
|
29
|
-
|
|
30
|
-
beforeEach(function() {
|
|
31
|
-
instance = new FastApi.VeriffSessionRequest();
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
var getProperty = function(object, getter, property) {
|
|
35
|
-
// Use getter method if present; otherwise, get the property directly.
|
|
36
|
-
if (typeof object[getter] === 'function')
|
|
37
|
-
return object[getter]();
|
|
38
|
-
else
|
|
39
|
-
return object[property];
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
var setProperty = function(object, setter, property, value) {
|
|
43
|
-
// Use setter method if present; otherwise, set the property directly.
|
|
44
|
-
if (typeof object[setter] === 'function')
|
|
45
|
-
object[setter](value);
|
|
46
|
-
else
|
|
47
|
-
object[property] = value;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
describe('VeriffSessionRequest', function() {
|
|
51
|
-
it('should create an instance of VeriffSessionRequest', function() {
|
|
52
|
-
// uncomment below and update the code to test VeriffSessionRequest
|
|
53
|
-
//var instance = new FastApi.VeriffSessionRequest();
|
|
54
|
-
//expect(instance).to.be.a(FastApi.VeriffSessionRequest);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it('should have the property userDocument (base name: "user_document")', function() {
|
|
58
|
-
// uncomment below and update the code to test the property userDocument
|
|
59
|
-
//var instance = new FastApi.VeriffSessionRequest();
|
|
60
|
-
//expect(instance).to.be();
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('should have the property documentType (base name: "document_type")', function() {
|
|
64
|
-
// uncomment below and update the code to test the property documentType
|
|
65
|
-
//var instance = new FastApi.VeriffSessionRequest();
|
|
66
|
-
//expect(instance).to.be();
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
}));
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* FastAPI
|
|
3
|
-
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
|
4
|
-
*
|
|
5
|
-
* The version of the OpenAPI document: 0.1.0
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
|
9
|
-
* https://openapi-generator.tech
|
|
10
|
-
* Do not edit the class manually.
|
|
11
|
-
*
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
(function(root, factory) {
|
|
15
|
-
if (typeof define === 'function' && define.amd) {
|
|
16
|
-
// AMD.
|
|
17
|
-
define(['expect.js', process.cwd()+'/src/index'], factory);
|
|
18
|
-
} else if (typeof module === 'object' && module.exports) {
|
|
19
|
-
// CommonJS-like environments that support module.exports, like Node.
|
|
20
|
-
factory(require('expect.js'), require(process.cwd()+'/src/index'));
|
|
21
|
-
} else {
|
|
22
|
-
// Browser globals (root is window)
|
|
23
|
-
factory(root.expect, root.FastApi);
|
|
24
|
-
}
|
|
25
|
-
}(this, function(expect, FastApi) {
|
|
26
|
-
'use strict';
|
|
27
|
-
|
|
28
|
-
var instance;
|
|
29
|
-
|
|
30
|
-
beforeEach(function() {
|
|
31
|
-
instance = new FastApi.VerifyRequest();
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
var getProperty = function(object, getter, property) {
|
|
35
|
-
// Use getter method if present; otherwise, get the property directly.
|
|
36
|
-
if (typeof object[getter] === 'function')
|
|
37
|
-
return object[getter]();
|
|
38
|
-
else
|
|
39
|
-
return object[property];
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
var setProperty = function(object, setter, property, value) {
|
|
43
|
-
// Use setter method if present; otherwise, set the property directly.
|
|
44
|
-
if (typeof object[setter] === 'function')
|
|
45
|
-
object[setter](value);
|
|
46
|
-
else
|
|
47
|
-
object[property] = value;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
describe('VerifyRequest', function() {
|
|
51
|
-
it('should create an instance of VerifyRequest', function() {
|
|
52
|
-
// uncomment below and update the code to test VerifyRequest
|
|
53
|
-
//var instance = new FastApi.VerifyRequest();
|
|
54
|
-
//expect(instance).to.be.a(FastApi.VerifyRequest);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it('should have the property attestation (base name: "attestation")', function() {
|
|
58
|
-
// uncomment below and update the code to test the property attestation
|
|
59
|
-
//var instance = new FastApi.VerifyRequest();
|
|
60
|
-
//expect(instance).to.be();
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('should have the property keyId (base name: "keyId")', function() {
|
|
64
|
-
// uncomment below and update the code to test the property keyId
|
|
65
|
-
//var instance = new FastApi.VerifyRequest();
|
|
66
|
-
//expect(instance).to.be();
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
}));
|
package/src/index.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import * as PolyguardApi from './generated/src/index.js';
|
|
2
|
-
import { PolyguardClient } from './PolyguardClient.js';
|
|
3
|
-
|
|
4
|
-
// UMD export for browser usage
|
|
5
|
-
if (typeof window !== 'undefined') {
|
|
6
|
-
window.Polyguard = window.Polyguard || {};
|
|
7
|
-
window.Polyguard.Client = PolyguardClient;
|
|
8
|
-
Object.assign(window.Polyguard, PolyguardApi);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
// Export PolyguardClient first to ensure it takes precedence
|
|
12
|
-
export { PolyguardClient };
|
|
13
|
-
// Then export everything else from the generated API
|
|
14
|
-
export * from './generated/src/index.js';
|
|
15
|
-
// Default export for easier usage
|
|
16
|
-
export default PolyguardClient;
|
package/src/messageHandler.js
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import { showSpinner, renderMobileButton, renderQRCode } from './ui.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Handle a WebSocket message event.
|
|
5
|
-
* @param {MessageEvent} event
|
|
6
|
-
* @param {Object} ctx - Context object with references from the verify() closure:
|
|
7
|
-
* { ws, qrDiv, isTargetMode, modal, cleanup, returnError, clearError, resolve, rawJwt }
|
|
8
|
-
*/
|
|
9
|
-
export function handleWebSocketMessage(event, ctx) {
|
|
10
|
-
const { ws, qrDiv, isTargetMode, cleanup, returnError, resolve, rawJwt } = ctx;
|
|
11
|
-
|
|
12
|
-
let data;
|
|
13
|
-
try {
|
|
14
|
-
data = JSON.parse(event.data);
|
|
15
|
-
} catch (e) {
|
|
16
|
-
console.error('Invalid message format from server', e);
|
|
17
|
-
returnError('Invalid message format from server');
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (!data) {
|
|
22
|
-
console.error('Unknown message type from server', data);
|
|
23
|
-
returnError('Unknown message type from server');
|
|
24
|
-
ws.close();
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Backend-initiated latency measurement
|
|
29
|
-
if (data.type === 'ping' && typeof data.seq !== 'undefined') {
|
|
30
|
-
ws.send(JSON.stringify({ type: 'pong', seq: data.seq }));
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (data.url) {
|
|
35
|
-
window.location.assign(data.url);
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (data.qr_url) {
|
|
40
|
-
const pcre = data.qr_url.match(/pcre=([^&]*)/);
|
|
41
|
-
console.log('pcre', pcre);
|
|
42
|
-
if (pcre) {
|
|
43
|
-
ws.send(JSON.stringify({ type: 'pong', seq: pcre[1] }));
|
|
44
|
-
}
|
|
45
|
-
if (qrDiv) {
|
|
46
|
-
const isMobile = /Mobi|Android/i.test(navigator.userAgent);
|
|
47
|
-
if (isMobile) {
|
|
48
|
-
renderMobileButton(qrDiv, data.qr_url, isTargetMode);
|
|
49
|
-
} else {
|
|
50
|
-
renderQRCode(qrDiv, data.qr_url);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (data.jwt) {
|
|
57
|
-
const redirectUrl = data.jwt.redirect_url;
|
|
58
|
-
const { sidebarUrl, link_uuid } = ctx;
|
|
59
|
-
|
|
60
|
-
// When sidebarUrl is configured and the server provides a redirect_url,
|
|
61
|
-
// the SDK handles the redirect (and optionally opens a sidebar popup).
|
|
62
|
-
if (sidebarUrl && redirectUrl) {
|
|
63
|
-
const hasMsftSession = document.cookie.includes('pg_msft_session');
|
|
64
|
-
// Mark the socket as intentionally closed BEFORE ws.close() so the
|
|
65
|
-
// 'close' event listener in verify() skips its own cleanup(). Otherwise
|
|
66
|
-
// the async close handler races with the synchronous button append below
|
|
67
|
-
// and wipes the qrDiv after we've put the button in it.
|
|
68
|
-
ctx.markClosed();
|
|
69
|
-
cleanup();
|
|
70
|
-
ws.close();
|
|
71
|
-
|
|
72
|
-
if (hasMsftSession) {
|
|
73
|
-
// Authenticated user — redirect directly, they'll see the in-Teams sidepanel
|
|
74
|
-
window.location.assign(redirectUrl);
|
|
75
|
-
resolve(rawJwt ? data : data.jwt);
|
|
76
|
-
} else {
|
|
77
|
-
// Anonymous user — show a "Join Meeting" button so the click provides
|
|
78
|
-
// the user gesture Chrome requires for window.open()
|
|
79
|
-
const targetEl = qrDiv || document.body;
|
|
80
|
-
const btn = document.createElement('button');
|
|
81
|
-
btn.id = 'polyguard-join-meeting';
|
|
82
|
-
btn.textContent = 'Join Meeting';
|
|
83
|
-
btn.style.cssText = 'padding:12px 24px;font-size:16px;cursor:pointer;border:none;border-radius:8px;background:#4CAF50;color:white;margin:16px auto;display:block;';
|
|
84
|
-
targetEl.appendChild(btn);
|
|
85
|
-
btn.addEventListener('click', () => {
|
|
86
|
-
const sidebarFullUrl = link_uuid
|
|
87
|
-
? `${sidebarUrl}?linkUuid=${link_uuid}`
|
|
88
|
-
: sidebarUrl;
|
|
89
|
-
window.open(
|
|
90
|
-
sidebarFullUrl,
|
|
91
|
-
'polyguard-sidebar',
|
|
92
|
-
'width=320,height=900,top=0,left=' + (window.screen.availWidth - 320)
|
|
93
|
-
);
|
|
94
|
-
window.location.assign(redirectUrl);
|
|
95
|
-
resolve(rawJwt ? data : data.jwt);
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
cleanup();
|
|
102
|
-
ws.close();
|
|
103
|
-
resolve(rawJwt ? data : data.jwt);
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
if (data.status) {
|
|
108
|
-
if (qrDiv) showSpinner(qrDiv);
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
if (data.error) {
|
|
113
|
-
returnError(data.error);
|
|
114
|
-
ws.close();
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
console.error('Unknown message type from server', data);
|
|
119
|
-
returnError('Unknown message type from server');
|
|
120
|
-
ws.close();
|
|
121
|
-
}
|
package/src/server.js
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
const DEFAULT_ALLOWED_PATHS = [
|
|
2
|
-
'POST /v2/ticket/',
|
|
3
|
-
'PUT /link/',
|
|
4
|
-
'GET /v2/preview/',
|
|
5
|
-
];
|
|
6
|
-
|
|
7
|
-
const HOP_BY_HOP = new Set([
|
|
8
|
-
'connection',
|
|
9
|
-
'keep-alive',
|
|
10
|
-
'proxy-authenticate',
|
|
11
|
-
'proxy-authorization',
|
|
12
|
-
'te',
|
|
13
|
-
'trailer',
|
|
14
|
-
'transfer-encoding',
|
|
15
|
-
'upgrade',
|
|
16
|
-
]);
|
|
17
|
-
|
|
18
|
-
function isAllowed(method, pathname, allowedPaths) {
|
|
19
|
-
const upper = method.toUpperCase();
|
|
20
|
-
for (const rule of allowedPaths) {
|
|
21
|
-
const idx = rule.indexOf(' ');
|
|
22
|
-
if (idx < 0) continue;
|
|
23
|
-
const ruleMethod = rule.slice(0, idx).toUpperCase();
|
|
24
|
-
const rulePrefix = rule.slice(idx + 1);
|
|
25
|
-
if (ruleMethod === upper && pathname.startsWith(rulePrefix)) {
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return false;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export function createProxyHandler(options = {}) {
|
|
33
|
-
const { apiKey, apiServer = 'api.polyguard.ai', allowedPaths = DEFAULT_ALLOWED_PATHS, pathPrefix = '/api/polyguard' } = options;
|
|
34
|
-
|
|
35
|
-
if (!apiKey) {
|
|
36
|
-
throw new Error('createProxyHandler: apiKey is required');
|
|
37
|
-
}
|
|
38
|
-
if (!apiServer) {
|
|
39
|
-
throw new Error('createProxyHandler: apiServer is required');
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return async function polyguardProxy(request) {
|
|
43
|
-
const url = new URL(request.url);
|
|
44
|
-
let pathname = url.pathname;
|
|
45
|
-
if (pathPrefix && pathname.startsWith(pathPrefix)) {
|
|
46
|
-
pathname = pathname.slice(pathPrefix.length) || '/';
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (!isAllowed(request.method, pathname, allowedPaths)) {
|
|
50
|
-
return new Response('Not Found', { status: 404 });
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const targetUrl = `https://${apiServer}${pathname}${url.search}`;
|
|
54
|
-
|
|
55
|
-
const forwardHeaders = new Headers();
|
|
56
|
-
for (const [name, value] of request.headers) {
|
|
57
|
-
const lower = name.toLowerCase();
|
|
58
|
-
if (lower === 'x-pg-api-key' || lower === 'authorization') continue;
|
|
59
|
-
if (HOP_BY_HOP.has(lower)) continue;
|
|
60
|
-
if (lower === 'host') continue;
|
|
61
|
-
forwardHeaders.set(name, value);
|
|
62
|
-
}
|
|
63
|
-
forwardHeaders.set('x-pg-api-key', apiKey);
|
|
64
|
-
|
|
65
|
-
const init = {
|
|
66
|
-
method: request.method,
|
|
67
|
-
headers: forwardHeaders,
|
|
68
|
-
redirect: 'manual',
|
|
69
|
-
};
|
|
70
|
-
if (request.method !== 'GET' && request.method !== 'HEAD') {
|
|
71
|
-
init.body = request.body;
|
|
72
|
-
init.duplex = 'half';
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const upstream = await fetch(targetUrl, init);
|
|
76
|
-
|
|
77
|
-
const responseHeaders = new Headers();
|
|
78
|
-
for (const [name, value] of upstream.headers) {
|
|
79
|
-
const lower = name.toLowerCase();
|
|
80
|
-
if (HOP_BY_HOP.has(lower)) continue;
|
|
81
|
-
if (lower === 'set-cookie') continue;
|
|
82
|
-
responseHeaders.set(name, value);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return new Response(upstream.body, {
|
|
86
|
-
status: upstream.status,
|
|
87
|
-
statusText: upstream.statusText,
|
|
88
|
-
headers: responseHeaders,
|
|
89
|
-
});
|
|
90
|
-
};
|
|
91
|
-
}
|
package/src/ticketService.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
export async function fetchTicket({ apiServer, proxyUrl, appId, link_uuid, requiredProofs, scanType }) {
|
|
2
|
-
const base = proxyUrl
|
|
3
|
-
? proxyUrl.replace(/\/$/, '')
|
|
4
|
-
: `https://${apiServer}`;
|
|
5
|
-
|
|
6
|
-
const ticketUrl = link_uuid
|
|
7
|
-
? `${base}/v2/ticket/${appId}/${link_uuid}`
|
|
8
|
-
: `${base}/v2/ticket/${appId}`;
|
|
9
|
-
|
|
10
|
-
const ticketRes = await fetch(ticketUrl, {
|
|
11
|
-
method: 'POST',
|
|
12
|
-
headers: { 'Content-Type': 'application/json' },
|
|
13
|
-
body: JSON.stringify({ requiredProofs, scanType }),
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
if (!ticketRes.ok) {
|
|
17
|
-
throw new Error('Failed to get ticket');
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const ticketData = await ticketRes.json();
|
|
21
|
-
const ticket = ticketData.ticket;
|
|
22
|
-
|
|
23
|
-
if (!ticket) {
|
|
24
|
-
throw new Error('No ticket returned from server');
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return ticket;
|
|
28
|
-
}
|
package/src/ui.js
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import QRCode from 'qrcode';
|
|
2
|
-
|
|
3
|
-
// Animated spinner SVG
|
|
4
|
-
export const LOADING_SPINNER = `<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 200 200" fill="none">
|
|
5
|
-
<style>
|
|
6
|
-
.spinner-circle {
|
|
7
|
-
animation: spin 1s linear infinite;
|
|
8
|
-
transform-origin: 100px 100px;
|
|
9
|
-
}
|
|
10
|
-
@keyframes spin {
|
|
11
|
-
from { transform: rotate(0deg); }
|
|
12
|
-
to { transform: rotate(360deg); }
|
|
13
|
-
}
|
|
14
|
-
</style>
|
|
15
|
-
<circle cx="100" cy="100" r="80" stroke="#e0e0e0" stroke-width="8" fill="none" />
|
|
16
|
-
<circle cx="100" cy="100" r="80" stroke="#407796" stroke-width="8" fill="none"
|
|
17
|
-
stroke-dasharray="251.2" stroke-dashoffset="188.4"
|
|
18
|
-
class="spinner-circle" stroke-linecap="round" />
|
|
19
|
-
</svg>`;
|
|
20
|
-
|
|
21
|
-
export function buildModal() {
|
|
22
|
-
const modal = document.createElement('div');
|
|
23
|
-
modal.style.position = 'fixed';
|
|
24
|
-
modal.style.top = '0';
|
|
25
|
-
modal.style.left = '0';
|
|
26
|
-
modal.style.width = '100vw';
|
|
27
|
-
modal.style.height = '100vh';
|
|
28
|
-
modal.style.background = 'rgba(0,0,0,0.45)';
|
|
29
|
-
modal.style.display = 'flex';
|
|
30
|
-
modal.style.alignItems = 'flex-start';
|
|
31
|
-
modal.style.justifyContent = 'center';
|
|
32
|
-
modal.style.overflowY = 'auto';
|
|
33
|
-
modal.style.paddingTop = '24px';
|
|
34
|
-
modal.style.zIndex = '2147483647';
|
|
35
|
-
modal.innerHTML = `
|
|
36
|
-
<div id="polyguard-modal-content" style="background: #fff; color: #222; border-radius: 16px; box-shadow: 0 8px 32px rgba(0,0,0,0.18); padding: 26px 19px 19px 19px; max-width: 312px; width: 100%; text-align: center; position: relative; z-index: 2147483647; font-family: 'IBM Plex Sans', 'Inter', 'Helvetica', 'Arial', sans-serif; margin: 0 auto; box-sizing: border-box;">
|
|
37
|
-
<button id="polyguard-modal-close" style="position: absolute; top: 10px; right: 10px; background: none; border: none; font-size: 18px; color: #222; cursor: pointer; z-index: 2;">×</button>
|
|
38
|
-
<h2 style="margin-top: 0; font-size: 1.04rem; font-weight: 700; color: #222;">Quick Identity Verification</h2>
|
|
39
|
-
<div style="font-size: 10px; color: #888; margin-bottom: 10px; font-weight: 500;">Powered by Polyguard</div>
|
|
40
|
-
<div id="polyguard-qr" style="width: 200px; height: 200px; margin: 0 auto 13px auto; display: flex; align-items: center; justify-content: center; background: #f4f8fb; border-radius: 10px;"></div>
|
|
41
|
-
<div style="margin-bottom: 10px; font-weight: 600; font-size: 13px; color: #222;">Scan this QR code to verify your identity.</div>
|
|
42
|
-
<ul style="text-align: left; margin: 0 0 13px 0; padding-left: 16px; font-size: 11px; color: #444;">
|
|
43
|
-
<li>We use the Polyguard service to verify your identity.</li>
|
|
44
|
-
<li>If you do not have the Polyguard app, the QR code will redirect you to download it from the App Store or Google Play.</li>
|
|
45
|
-
<li>Your credentials remain private on your device.</li>
|
|
46
|
-
</ul>
|
|
47
|
-
<div style="display: flex; justify-content: center; gap: 10px; font-size: 10px; color: #5a6c7d; margin-bottom: 10px; flex-wrap: wrap;">
|
|
48
|
-
<span>🔒 Encrypted</span>
|
|
49
|
-
<span>📱 On-device</span>
|
|
50
|
-
<span>⏲ Expires</span>
|
|
51
|
-
</div>
|
|
52
|
-
<div id="polyguard-error" style="color: #b31d28; font-size: 11px; margin-bottom: 6px; display: none;"></div>
|
|
53
|
-
<button id="polyguard-modal-cancel" style="background: #407796; color: #fff; font-weight: 600; border-radius: 8px; border: none; padding: 8px 26px; font-size: 13px; cursor: pointer; margin-top: 6px; width: 100%; max-width: 192px;">Cancel</button>
|
|
54
|
-
</div>
|
|
55
|
-
`;
|
|
56
|
-
return modal;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export function showSpinner(qrDiv) {
|
|
60
|
-
qrDiv.innerHTML = LOADING_SPINNER;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export function renderMobileButton(qrDiv, qrUrl, isTargetMode) {
|
|
64
|
-
qrDiv.innerHTML = `<button id="polyguard-open-app-button" style="background: #407796; color: #fff; font-weight: 600; border-radius: 8px; border: none; padding: 10px 32px; font-size: 16px; cursor: pointer;">Open Polyguard App</button>`;
|
|
65
|
-
qrDiv.style.background = 'transparent';
|
|
66
|
-
qrDiv.querySelector('#polyguard-open-app-button').onclick = () => window.location.assign(qrUrl);
|
|
67
|
-
|
|
68
|
-
// Update surrounding text only in modal mode
|
|
69
|
-
if (!isTargetMode) {
|
|
70
|
-
const instructionText = qrDiv.nextElementSibling;
|
|
71
|
-
if (instructionText) {
|
|
72
|
-
instructionText.textContent = 'Tap the button to verify with the Polyguard app.';
|
|
73
|
-
}
|
|
74
|
-
const instructionList = instructionText.nextElementSibling;
|
|
75
|
-
if (instructionList && instructionList.children[1]) {
|
|
76
|
-
instructionList.children[1].textContent = 'If you do not have the Polyguard app, you will be redirected to download it.';
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export function renderQRCode(qrDiv, qrUrl) {
|
|
82
|
-
const startTime = Date.now();
|
|
83
|
-
console.log('time before qr code', startTime);
|
|
84
|
-
QRCode.toString(qrUrl, { type: 'svg' }, (err, svg) => {
|
|
85
|
-
if (!err) qrDiv.innerHTML = svg;
|
|
86
|
-
});
|
|
87
|
-
console.log('time to generate qr code', Date.now() - startTime);
|
|
88
|
-
}
|