securenow 5.16.1 → 5.16.2
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/cli/auth.js +51 -12
- package/package.json +1 -1
package/cli/auth.js
CHANGED
|
@@ -41,6 +41,8 @@ async function loginWithBrowser() {
|
|
|
41
41
|
const appUrl = config.getAppUrl();
|
|
42
42
|
|
|
43
43
|
return new Promise((resolve, reject) => {
|
|
44
|
+
let pendingToken = null;
|
|
45
|
+
|
|
44
46
|
const server = http.createServer((req, res) => {
|
|
45
47
|
const url = new URL(req.url, `http://localhost`);
|
|
46
48
|
|
|
@@ -48,7 +50,7 @@ async function loginWithBrowser() {
|
|
|
48
50
|
const token = url.searchParams.get('token');
|
|
49
51
|
const error = url.searchParams.get('error');
|
|
50
52
|
|
|
51
|
-
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
53
|
+
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
52
54
|
|
|
53
55
|
if (error) {
|
|
54
56
|
res.end('<html><body style="font-family:system-ui;text-align:center;padding:60px"><h2>Authentication Failed</h2><p>You can close this window.</p></body></html>');
|
|
@@ -58,18 +60,45 @@ async function loginWithBrowser() {
|
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
if (token) {
|
|
63
|
+
pendingToken = token;
|
|
61
64
|
const payload = decodeJwtPayload(token);
|
|
62
|
-
const email = payload?.email || '';
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
65
|
+
const email = payload?.email || 'unknown account';
|
|
66
|
+
const safeEmail = email.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
67
|
+
const port = server.address().port;
|
|
68
|
+
const switchUrl = `${appUrl}/cli/auth?callback=http://localhost:${port}/callback&force_login=1`;
|
|
69
|
+
|
|
70
|
+
res.end([
|
|
71
|
+
'<!DOCTYPE html><html><head><meta charset="utf-8"><title>SecureNow CLI Login</title></head>',
|
|
72
|
+
'<body style="font-family:system-ui,sans-serif;text-align:center;padding:60px;margin:0;background:#fafafa">',
|
|
73
|
+
'<div style="max-width:420px;margin:0 auto;background:#fff;border-radius:12px;padding:40px 32px;box-shadow:0 2px 12px rgba(0,0,0,.08)">',
|
|
74
|
+
'<div style="width:56px;height:56px;margin:0 auto 20px;background:#f0fdf4;border-radius:50%;display:flex;align-items:center;justify-content:center">',
|
|
75
|
+
'<svg width="28" height="28" fill="none" viewBox="0 0 24 24"><path d="M12 2a5 5 0 015 5v1a2 2 0 012 2v8a2 2 0 01-2 2H7a2 2 0 01-2-2v-8a2 2 0 012-2V7a5 5 0 015-5zm0 2a3 3 0 00-3 3v1h6V7a3 3 0 00-3-3z" fill="#22c55e"/></svg>',
|
|
76
|
+
'</div>',
|
|
77
|
+
'<h2 style="margin:0 0 8px;font-size:22px;color:#111">Connect to SecureNow CLI</h2>',
|
|
78
|
+
`<p style="margin:0 0 24px;color:#666;font-size:15px">You are signing in as</p>`,
|
|
79
|
+
`<div style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;padding:14px 18px;margin:0 0 28px">`,
|
|
80
|
+
`<span style="font-size:17px;font-weight:600;color:#0f172a">${safeEmail}</span>`,
|
|
81
|
+
'</div>',
|
|
82
|
+
'<button id="confirm-btn" style="width:100%;padding:13px 24px;font-size:16px;font-weight:600;color:#fff;background:#22c55e;border:none;border-radius:8px;cursor:pointer;transition:background .15s" ',
|
|
83
|
+
'onmouseover="this.style.background=\'#16a34a\'" onmouseout="this.style.background=\'#22c55e\'">',
|
|
84
|
+
'Confirm & Continue</button>',
|
|
85
|
+
`<p style="margin:20px 0 0"><a href="${switchUrl}" style="color:#6366f1;font-size:14px;text-decoration:none" `,
|
|
86
|
+
'onmouseover="this.style.textDecoration=\'underline\'" onmouseout="this.style.textDecoration=\'none\'">Use a different account</a></p>',
|
|
87
|
+
'<div id="done-msg" style="display:none;margin-top:24px">',
|
|
88
|
+
'<p style="color:#22c55e;font-weight:600;font-size:17px">\u2713 Connected! You can close this window.</p>',
|
|
89
|
+
'</div>',
|
|
90
|
+
'</div>',
|
|
91
|
+
'<script>',
|
|
92
|
+
'document.getElementById("confirm-btn").addEventListener("click", function(){',
|
|
93
|
+
' this.disabled=true;this.textContent="Connecting\u2026";this.style.background="#86efac";this.style.cursor="default";',
|
|
94
|
+
` fetch("/confirm").then(function(){`,
|
|
95
|
+
' document.getElementById("confirm-btn").style.display="none";',
|
|
96
|
+
' document.getElementById("done-msg").style.display="block";',
|
|
97
|
+
' });',
|
|
98
|
+
'});',
|
|
99
|
+
'</script>',
|
|
100
|
+
'</body></html>',
|
|
101
|
+
].join(''));
|
|
73
102
|
return;
|
|
74
103
|
}
|
|
75
104
|
|
|
@@ -79,6 +108,16 @@ async function loginWithBrowser() {
|
|
|
79
108
|
return;
|
|
80
109
|
}
|
|
81
110
|
|
|
111
|
+
if (url.pathname === '/confirm' && pendingToken) {
|
|
112
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
113
|
+
res.end('{"ok":true}');
|
|
114
|
+
const token = pendingToken;
|
|
115
|
+
pendingToken = null;
|
|
116
|
+
server.close();
|
|
117
|
+
resolve(token);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
82
121
|
res.writeHead(404);
|
|
83
122
|
res.end();
|
|
84
123
|
});
|
package/package.json
CHANGED