casdoor 1.2.0 → 1.3.0
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/manifest.json +2 -2
- package/package.json +1 -1
- package/src/oauth.js +163 -24
- package/src/popup.js +33 -18
- package/src/sdk.js +4 -1
package/manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "Casdoor",
|
|
3
|
-
"description": "
|
|
2
|
+
"name": "Casdoor Browser Plugin",
|
|
3
|
+
"description": "Casdoor Browser Plugin can help the users automatically log into applications protected by Casdoor identity provider.",
|
|
4
4
|
"version": "1.0.0",
|
|
5
5
|
"manifest_version": 3,
|
|
6
6
|
"permissions": [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "casdoor",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "The Casdoor extension can help browser users automatically log into applications protected by Casdoor single-sign-on (SSO) system.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"semantic-release": "semantic-release"
|
package/src/oauth.js
CHANGED
|
@@ -18,33 +18,59 @@ const CasdoorConfig = {
|
|
|
18
18
|
applicationName: "",
|
|
19
19
|
endpoint: "",
|
|
20
20
|
};
|
|
21
|
-
chrome.storage.sync.get("applicationName", ({applicationName}) => {
|
|
22
|
-
if (applicationName) {
|
|
23
|
-
CasdoorConfig.applicationName = applicationName;
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
chrome.storage.sync.get("endpoint", ({endpoint}) => {
|
|
27
|
-
if (endpoint) {
|
|
28
|
-
CasdoorConfig.endpoint = endpoint;
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
21
|
|
|
32
|
-
|
|
22
|
+
let sdk;
|
|
23
|
+
sdk = new Sdk(CasdoorConfig);
|
|
24
|
+
|
|
25
|
+
function getStorageData(keys) {
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
chrome.storage.sync.get(keys, (data) => {
|
|
28
|
+
if (chrome.runtime.lastError) {
|
|
29
|
+
reject(chrome.runtime.lastError.message);
|
|
30
|
+
} else {
|
|
31
|
+
resolve(data);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function initInputParamSdk(){
|
|
38
|
+
return new Promise((resolve, reject) => {
|
|
39
|
+
Promise.all([getStorageData("applicationName"), getStorageData("endpoint")])
|
|
40
|
+
.then(([applicationData, endpointData]) => {
|
|
41
|
+
const applicationName = applicationData.applicationName;
|
|
42
|
+
const endpoint = endpointData.endpoint;
|
|
43
|
+
|
|
44
|
+
if (applicationName && endpoint) {
|
|
45
|
+
CasdoorConfig.applicationName = applicationName;
|
|
46
|
+
CasdoorConfig.endpoint = endpoint;
|
|
47
|
+
}
|
|
48
|
+
sdk = new Sdk(CasdoorConfig);
|
|
49
|
+
resolve(sdk);
|
|
50
|
+
})
|
|
51
|
+
.catch((error) => {
|
|
52
|
+
console.error("init SDK failed:", error);
|
|
53
|
+
reject(error);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
}
|
|
33
57
|
|
|
34
58
|
// eslint-disable-next-line no-unused-vars
|
|
35
59
|
function login() {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
60
|
+
initInputParamSdk().then((sdk) => {
|
|
61
|
+
sdk.login((accessToken) => {
|
|
62
|
+
if (accessToken) {
|
|
63
|
+
chrome.storage.sync.set({accessToken}, () => {
|
|
64
|
+
sdk
|
|
65
|
+
.getUserProfile(accessToken)
|
|
66
|
+
.then((userProfile) => displayUserProfile(userProfile));
|
|
67
|
+
});
|
|
68
|
+
setInputDisabledState(true, "endpoint", "applicationName");
|
|
69
|
+
} else {
|
|
70
|
+
alert("Login failed!");
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
})
|
|
48
74
|
}
|
|
49
75
|
|
|
50
76
|
// eslint-disable-next-line no-unused-vars
|
|
@@ -55,9 +81,13 @@ function logout() {
|
|
|
55
81
|
|
|
56
82
|
function displayUserProfile(userProfile) {
|
|
57
83
|
document.getElementById("user").innerHTML = `
|
|
58
|
-
<img alt="${userProfile.name}" src="${userProfile.picture}" width="50px"
|
|
84
|
+
<img alt="${userProfile.name}" src="${userProfile.picture}" width="50px"/>
|
|
59
85
|
<p>Hi, ${userProfile.name}</p>
|
|
60
86
|
`;
|
|
87
|
+
setTimeout(function() {
|
|
88
|
+
updateDisabledInput("endpoint", userProfile.iss)
|
|
89
|
+
updateDisabledInput("applicationName", userProfile.applicationName)
|
|
90
|
+
}, 100);
|
|
61
91
|
document.getElementById("loginOrLogout").innerText = "Logout";
|
|
62
92
|
}
|
|
63
93
|
|
|
@@ -66,6 +96,12 @@ function clearUserProfile() {
|
|
|
66
96
|
document.getElementById("loginOrLogout").innerText = "Login";
|
|
67
97
|
}
|
|
68
98
|
|
|
99
|
+
function updateDisabledInput(id,value){
|
|
100
|
+
document.getElementById(id).disabled = false;
|
|
101
|
+
document.getElementById(id).value = value;
|
|
102
|
+
document.getElementById(id).disabled = true;
|
|
103
|
+
}
|
|
104
|
+
|
|
69
105
|
function setInputDisabledState(disabledState, ...elementIds) {
|
|
70
106
|
elementIds.forEach(elementId => {
|
|
71
107
|
const inputElement = document.getElementById(elementId);
|
|
@@ -76,3 +112,106 @@ function setInputDisabledState(disabledState, ...elementIds) {
|
|
|
76
112
|
}
|
|
77
113
|
});
|
|
78
114
|
}
|
|
115
|
+
|
|
116
|
+
const intervalDetectToken = setInterval(getDomAccessToken, 3000);
|
|
117
|
+
|
|
118
|
+
let accessToken;
|
|
119
|
+
let applicationName;
|
|
120
|
+
|
|
121
|
+
function getDomAccessToken() {
|
|
122
|
+
if(window.location.pathname != "/src/popup.html"){
|
|
123
|
+
accessToken = document.getElementById("CasdoorAccessToken").getAttribute("value");
|
|
124
|
+
applicationName = document.getElementById("CasdoorApplicationName").getAttribute("value");
|
|
125
|
+
if (accessToken && applicationName) {
|
|
126
|
+
sdk.getUserProfile(accessToken).then((userProfile) => {
|
|
127
|
+
userProfile.applicationName = applicationName;
|
|
128
|
+
if(userProfile){
|
|
129
|
+
showNotification(confirmCallback, userProfile);
|
|
130
|
+
}
|
|
131
|
+
clearInterval(intervalDetectToken);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
} else{
|
|
135
|
+
clearInterval(intervalDetectToken);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function confirmCallback(userProfile) {
|
|
140
|
+
if (accessToken && userProfile) {
|
|
141
|
+
chrome.storage.sync.set({ accessToken: accessToken,userProfile: userProfile});
|
|
142
|
+
} else {
|
|
143
|
+
alert("Login failed!");
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
function showNotification(confirmCallback, userProfile) {
|
|
149
|
+
const notification = document.createElement("div");
|
|
150
|
+
const userDiv = document.createElement("div");
|
|
151
|
+
const endpointDataDiv = document.createElement("div");
|
|
152
|
+
const applicationNameDataDiv = document.createElement("div");
|
|
153
|
+
const buttonDiv = document.createElement("div");
|
|
154
|
+
const confirmButton = document.createElement("button");
|
|
155
|
+
const cancelButton = document.createElement("button");
|
|
156
|
+
|
|
157
|
+
notification.style.position = "fixed";
|
|
158
|
+
notification.style.top = "10px";
|
|
159
|
+
notification.style.right = "10px";
|
|
160
|
+
notification.style.padding = "10px";
|
|
161
|
+
notification.style.margin = "10px";
|
|
162
|
+
notification.style.backgroundColor = "#eceff7";
|
|
163
|
+
notification.style.color = "#000000";
|
|
164
|
+
|
|
165
|
+
userDiv.style.display = "flex";
|
|
166
|
+
userDiv.style.margin = "10px";
|
|
167
|
+
userDiv.style.justifyContent = 'center';
|
|
168
|
+
userDiv.style.alignItems = 'center';
|
|
169
|
+
|
|
170
|
+
endpointDataDiv.style.marginBottom = "10px";
|
|
171
|
+
endpointDataDiv.style.marginTop = "10px";
|
|
172
|
+
|
|
173
|
+
buttonDiv.style.marginTop = "10px";
|
|
174
|
+
buttonDiv.style.display = "flex";
|
|
175
|
+
buttonDiv.style.justifyContent = "space-between";
|
|
176
|
+
|
|
177
|
+
notification.textContent = "Whether to log in to the current account?";
|
|
178
|
+
|
|
179
|
+
userDiv.innerHTML=`
|
|
180
|
+
<img alt="${userProfile.name}" src="${userProfile.picture}" width="50px" style="margin-right: 10px;"/>
|
|
181
|
+
<p>${userProfile.name}</p>
|
|
182
|
+
`
|
|
183
|
+
|
|
184
|
+
cancelButton.textContent = "Cancel";
|
|
185
|
+
|
|
186
|
+
confirmButton.textContent = "OK";
|
|
187
|
+
|
|
188
|
+
endpointDataDiv.innerHTML = `endpoint: <span style="background-color: lightgray;">${userProfile.iss}</span>`;
|
|
189
|
+
|
|
190
|
+
applicationNameDataDiv.innerHTML = `applicationName: <span style="background-color: lightgray;">${userProfile.applicationName}</span>`;
|
|
191
|
+
|
|
192
|
+
confirmButton.onclick = () => {
|
|
193
|
+
if (confirmCallback && typeof confirmCallback === "function") {
|
|
194
|
+
confirmCallback(userProfile);
|
|
195
|
+
}
|
|
196
|
+
document.body.removeChild(notification);
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
cancelButton.onclick = () => {
|
|
200
|
+
document.body.removeChild(notification);
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
notification.appendChild(userDiv);
|
|
204
|
+
notification.appendChild(endpointDataDiv);
|
|
205
|
+
notification.appendChild(applicationNameDataDiv);
|
|
206
|
+
buttonDiv.appendChild(cancelButton);
|
|
207
|
+
buttonDiv.appendChild(confirmButton);
|
|
208
|
+
notification.appendChild(buttonDiv);
|
|
209
|
+
document.body.appendChild(notification);
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
setTimeout(() => {
|
|
213
|
+
if(document.body.contains(notification)){
|
|
214
|
+
document.body.removeChild(notification);
|
|
215
|
+
}
|
|
216
|
+
}, 5000);
|
|
217
|
+
}
|
package/src/popup.js
CHANGED
|
@@ -29,25 +29,32 @@ document.addEventListener("DOMContentLoaded", function() {
|
|
|
29
29
|
document.addEventListener("DOMContentLoaded", function() {
|
|
30
30
|
const loginOrLogoutDom = document.getElementById("loginOrLogout");
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
loginOrLogoutDom.innerText = accessToken ? "Logout" : "Login";
|
|
32
|
+
loginOrLogoutDom.innerText = accessToken ? "Logout" : "Login";
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
34
|
+
Promise.all([getStorageData("accessToken"), getStorageData("userProfile")])
|
|
35
|
+
.then(([accessToken, userProfile]) => {
|
|
36
|
+
if (accessToken.accessToken && userProfile.userProfile) {
|
|
37
|
+
displayUserProfile(userProfile.userProfile)
|
|
38
|
+
setInputDisabledState(true, "endpoint", "applicationName");
|
|
39
|
+
} else {
|
|
40
|
+
clearUserProfile();
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
.catch((error) => {
|
|
44
|
+
console.error("init SDK failed:", error);
|
|
45
|
+
reject(error);
|
|
46
|
+
});
|
|
44
47
|
|
|
45
48
|
loginOrLogoutDom.addEventListener("click", function() {
|
|
46
49
|
chrome.storage.sync.get("accessToken", ({accessToken}) => {
|
|
47
50
|
if (accessToken) {
|
|
48
51
|
logout();
|
|
49
52
|
} else {
|
|
50
|
-
|
|
53
|
+
setInput()
|
|
54
|
+
.then(login())
|
|
55
|
+
.catch(error => {
|
|
56
|
+
console.error('Error login:', error);
|
|
57
|
+
});
|
|
51
58
|
}
|
|
52
59
|
});
|
|
53
60
|
});
|
|
@@ -60,9 +67,6 @@ document.addEventListener("DOMContentLoaded", function() {
|
|
|
60
67
|
applicationNameDom.value = applicationName;
|
|
61
68
|
}
|
|
62
69
|
});
|
|
63
|
-
applicationNameDom.addEventListener("input", function(e) {
|
|
64
|
-
chrome.storage.sync.set({applicationName: e.target.value});
|
|
65
|
-
});
|
|
66
70
|
|
|
67
71
|
const endpointDom = document.getElementById("endpoint");
|
|
68
72
|
chrome.storage.sync.get("endpoint", ({endpoint}) => {
|
|
@@ -70,7 +74,18 @@ document.addEventListener("DOMContentLoaded", function() {
|
|
|
70
74
|
endpointDom.value = endpoint;
|
|
71
75
|
}
|
|
72
76
|
});
|
|
73
|
-
endpointDom.addEventListener("input", function(e) {
|
|
74
|
-
chrome.storage.sync.set({endpoint: e.target.value});
|
|
75
|
-
});
|
|
76
77
|
});
|
|
78
|
+
|
|
79
|
+
function setInput() {
|
|
80
|
+
return new Promise((resolve, reject) => {
|
|
81
|
+
const endpointDom = document.getElementById("endpoint");
|
|
82
|
+
const applicationNameDom = document.getElementById("applicationName");
|
|
83
|
+
chrome.storage.sync.set({ endpoint: endpointDom.value, applicationName: applicationNameDom.value }, function() {
|
|
84
|
+
if (chrome.runtime.lastError) {
|
|
85
|
+
reject(chrome.runtime.lastError.message);
|
|
86
|
+
} else {
|
|
87
|
+
resolve();
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
}
|
package/src/sdk.js
CHANGED
|
@@ -125,6 +125,9 @@ class Sdk {
|
|
|
125
125
|
};
|
|
126
126
|
return fetch(applicationUrl, requestConfig)
|
|
127
127
|
.then((response) => response.json())
|
|
128
|
-
.catch((error) =>
|
|
128
|
+
.catch((error) => {
|
|
129
|
+
console.error(error)
|
|
130
|
+
alert("failed to get application");
|
|
131
|
+
});
|
|
129
132
|
}
|
|
130
133
|
}
|