capacitor-sso-webview 0.0.3 → 0.0.5

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.
@@ -16,190 +16,196 @@ import android.widget.TextView;
16
16
 
17
17
  public class SSOWebView {
18
18
 
19
- public interface Listener {
20
- void onRedirectIntercepted(String url, String code, String state, String body);
21
- void onCancelled();
22
- }
23
-
24
- private Dialog dialog;
25
- private WebView webView;
26
- private boolean alreadyRedirected = false;
27
-
28
- public void open(
29
- final Activity activity,
30
- final String url,
31
- final String redirectHost,
32
- final String redirectPathContains,
33
- final String title,
34
- final Listener listener
35
- ) {
36
- alreadyRedirected = false;
37
-
38
- dialog = new Dialog(activity, android.R.style.Theme_Light_NoTitleBar_Fullscreen);
39
-
40
- LinearLayout root = new LinearLayout(activity);
41
- root.setOrientation(LinearLayout.VERTICAL);
42
- root.setLayoutParams(new LinearLayout.LayoutParams(
43
- ViewGroup.LayoutParams.MATCH_PARENT,
44
- ViewGroup.LayoutParams.MATCH_PARENT
45
- ));
46
-
47
- /* ── Header bar ── */
48
- LinearLayout header = new LinearLayout(activity);
49
- header.setOrientation(LinearLayout.HORIZONTAL);
50
- header.setBackgroundColor(Color.parseColor("#1A2B4A"));
51
- header.setPadding(48, 72, 48, 48);
52
- header.setGravity(Gravity.CENTER_VERTICAL);
53
- header.setLayoutParams(new LinearLayout.LayoutParams(
54
- ViewGroup.LayoutParams.MATCH_PARENT,
55
- ViewGroup.LayoutParams.WRAP_CONTENT
56
- ));
57
-
58
- TextView tvTitle = new TextView(activity);
59
- tvTitle.setText(title != null ? title : "Login");
60
- tvTitle.setTextColor(Color.WHITE);
61
- tvTitle.setTextSize(16);
62
- tvTitle.setLayoutParams(new LinearLayout.LayoutParams(
63
- 0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f
64
- ));
65
-
66
- TextView btnClose = new TextView(activity);
67
- btnClose.setText("Tutup");
68
- btnClose.setTextColor(Color.WHITE);
69
- btnClose.setTextSize(14);
70
- btnClose.setPadding(32, 16, 16, 16);
71
- btnClose.setOnClickListener(v -> {
72
- boolean wasRedirected = alreadyRedirected;
73
- dismiss();
74
- if (!wasRedirected && listener != null) listener.onCancelled();
75
- });
76
-
77
- header.addView(tvTitle);
78
- header.addView(btnClose);
79
-
80
- /* ── WebView ── */
81
- webView = new WebView(activity);
82
- WebSettings s = webView.getSettings();
83
- s.setJavaScriptEnabled(true);
84
- s.setDomStorageEnabled(true);
85
- s.setDatabaseEnabled(true);
86
- s.setUseWideViewPort(true);
87
- s.setLoadWithOverviewMode(true);
88
- s.setSupportZoom(false);
89
- s.setJavaScriptCanOpenWindowsAutomatically(true);
90
-
91
- CookieManager cm = CookieManager.getInstance();
92
- cm.setAcceptCookie(true);
93
- cm.setAcceptThirdPartyCookies(webView, true);
94
-
95
- webView.setWebViewClient(new WebViewClient() {
96
-
97
- @Override
98
- public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
99
- Uri u = request.getUrl();
100
- String host = u.getHost();
101
- String path = u.getPath();
102
-
103
- boolean isRedirect =
104
- host != null && host.equalsIgnoreCase(redirectHost) &&
105
- path != null && path.toLowerCase()
106
- .contains(redirectPathContains.toLowerCase());
107
-
108
- if (isRedirect && !alreadyRedirected) {
109
- alreadyRedirected = true;
110
- /* Biarkan WebView navigate — server akan return JSON body */
111
- return false;
19
+ public interface Listener {
20
+ void onRedirectIntercepted(String url, String code, String state, String body);
21
+
22
+ void onCancelled();
23
+ }
24
+
25
+ private Dialog dialog;
26
+ private WebView webView;
27
+ private boolean alreadyRedirected = false;
28
+
29
+ public void open(
30
+ final Activity activity,
31
+ final String url,
32
+ final String redirectHost,
33
+ final String redirectPathContains,
34
+ final String title,
35
+ final Listener listener) {
36
+ alreadyRedirected = false;
37
+
38
+ dialog = new Dialog(activity, android.R.style.Theme_Light_NoTitleBar_Fullscreen);
39
+
40
+ LinearLayout root = new LinearLayout(activity);
41
+ root.setOrientation(LinearLayout.VERTICAL);
42
+ root.setLayoutParams(new LinearLayout.LayoutParams(
43
+ ViewGroup.LayoutParams.MATCH_PARENT,
44
+ ViewGroup.LayoutParams.MATCH_PARENT));
45
+
46
+ /* ── Header bar ── */
47
+ LinearLayout header = new LinearLayout(activity);
48
+ header.setOrientation(LinearLayout.HORIZONTAL);
49
+ header.setBackgroundColor(Color.parseColor("#1A2B4A"));
50
+ header.setPadding(48, 72, 48, 48);
51
+ header.setGravity(Gravity.CENTER_VERTICAL);
52
+ header.setLayoutParams(new LinearLayout.LayoutParams(
53
+ ViewGroup.LayoutParams.MATCH_PARENT,
54
+ ViewGroup.LayoutParams.WRAP_CONTENT));
55
+
56
+ TextView tvTitle = new TextView(activity);
57
+ tvTitle.setText(title != null ? title : "Login");
58
+ tvTitle.setTextColor(Color.WHITE);
59
+ tvTitle.setTextSize(16);
60
+ tvTitle.setLayoutParams(new LinearLayout.LayoutParams(
61
+ 0, ViewGroup.LayoutParams.WRAP_CONTENT, 1 f));
62
+
63
+ TextView btnClose = new TextView(activity);
64
+ btnClose.setText("Tutup");
65
+ btnClose.setTextColor(Color.WHITE);
66
+ btnClose.setTextSize(14);
67
+ btnClose.setPadding(32, 16, 16, 16);
68
+ btnClose.setOnClickListener(v -> {
69
+ boolean wasRedirected = alreadyRedirected;
70
+ dismiss();
71
+ if (!wasRedirected && listener != null)
72
+ listener.onCancelled();
73
+ });
74
+
75
+ header.addView(tvTitle);
76
+ header.addView(btnClose);
77
+
78
+ /* ── WebView ── */
79
+ webView = new WebView(activity);
80
+ WebSettings s = webView.getSettings();
81
+ s.setJavaScriptEnabled(true);
82
+ s.setDomStorageEnabled(true);
83
+ s.setDatabaseEnabled(true);
84
+ s.setUseWideViewPort(true);
85
+ s.setLoadWithOverviewMode(true);
86
+ s.setSupportZoom(false);
87
+ s.setJavaScriptCanOpenWindowsAutomatically(true);
88
+
89
+ CookieManager cm = CookieManager.getInstance();
90
+ cm.setAcceptCookie(true);
91
+ cm.setAcceptThirdPartyCookies(webView, true);
92
+
93
+ webView.setWebViewClient(new WebViewClient() {
94
+
95
+ @Override
96
+ public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
97
+ Uri u = request.getUrl();
98
+ String host = u.getHost();
99
+ String path = u.getPath();
100
+
101
+ boolean isRedirect = host != null && host.equalsIgnoreCase(redirectHost) &&
102
+ path != null && path.toLowerCase()
103
+ .contains(redirectPathContains.toLowerCase());
104
+
105
+ if (isRedirect && !alreadyRedirected) {
106
+ alreadyRedirected = true;
107
+ /* Biarkan WebView navigate — server akan return JSON body */
108
+ return false;
109
+ }
110
+ return false;
111
+ }
112
+
113
+ @Override
114
+ public void onPageFinished(WebView view, String pageUrl) {
115
+ super.onPageFinished(view, pageUrl);
116
+
117
+ Uri u = Uri.parse(pageUrl);
118
+ String host = u.getHost();
119
+ String path = u.getPath();
120
+
121
+ boolean isRedirectPage = host != null && host.equalsIgnoreCase(redirectHost) &&
122
+ path != null && path.toLowerCase()
123
+ .contains(redirectPathContains.toLowerCase());
124
+
125
+ if (!isRedirectPage)
126
+ return;
127
+
128
+ final String finalUrl = pageUrl;
129
+ final String finalCode = u.getQueryParameter("code") != null ?
130
+ u.getQueryParameter("code") :
131
+ "";
132
+ final String finalState = u.getQueryParameter("state") != null ?
133
+ u.getQueryParameter("state") :
134
+ "";
135
+
136
+ /* Delay 150ms — beri waktu body JSON ter-render ke DOM */
137
+ view.postDelayed(new Runnable() {
138
+ @Override
139
+ public void run() {
140
+ if (webView == null) return;
141
+ webView.evaluateJavascript(
142
+ "(function(){" +
143
+ " var t = document.body" +
144
+ " ? (document.body.innerText || document.body.textContent || '')" +
145
+ " : '';" +
146
+ " return t.trim();" +
147
+ "})()",
148
+ value -> {
149
+ String body = value;
150
+ if (body != null) {
151
+ if (body.startsWith("\"") && body.endsWith("\""))
152
+ body = body.substring(1, body.length() - 1);
153
+ body = body.replace("\\\"", "\"")
154
+ .replace("\\n", "\n")
155
+ .replace("\\r", "")
156
+ .replace("\\/", "/");
112
157
  }
113
- return false;
114
- }
115
-
116
- @Override
117
- public void onPageFinished(WebView view, String pageUrl) {
118
- super.onPageFinished(view, pageUrl);
119
-
120
- Uri u = Uri.parse(pageUrl);
121
- String host = u.getHost();
122
- String path = u.getPath();
123
-
124
- boolean isRedirectPage =
125
- host != null && host.equalsIgnoreCase(redirectHost) &&
126
- path != null && path.toLowerCase()
127
- .contains(redirectPathContains.toLowerCase());
128
-
129
- if (!isRedirectPage) return;
130
-
131
- String code = u.getQueryParameter("code");
132
- String state = u.getQueryParameter("state");
133
- final String finalUrl = pageUrl;
134
- final String finalCode = code != null ? code : "";
135
- final String finalState = state != null ? state : "";
136
-
137
- /* Baca body JSON via evaluateJavascript — tidak fetch ulang */
138
- view.evaluateJavascript(
139
- "(function(){ return document.body ? document.body.innerText : ''; })()",
140
- value -> {
141
- /* Unescape JS string result */
142
- String body = value;
143
- if (body != null) {
144
- if (body.startsWith("\"") && body.endsWith("\"")) {
145
- body = body.substring(1, body.length() - 1);
146
- }
147
- body = body.replace("\\\"", "\"")
148
- .replace("\\n", "\n")
149
- .replace("\\r", "")
150
- .replace("\\/", "/");
151
- }
152
-
153
- final String finalBody = body != null ? body : "";
154
- android.util.Log.d("SSOWebView",
155
- "body len=" + finalBody.length() +
156
- " preview=" + finalBody.substring(0, Math.min(120, finalBody.length())));
157
-
158
- /* Tutup dialog setelah body dibaca */
159
- activity.runOnUiThread(this::dismiss);
160
-
161
- if (listener != null) {
162
- listener.onRedirectIntercepted(
163
- finalUrl, finalCode, finalState, finalBody
164
- );
165
- }
166
- }
167
- );
168
- }
169
-
170
- private void dismiss() {
171
- SSOWebView.this.dismiss();
172
- }
173
- });
174
-
175
- webView.setLayoutParams(new LinearLayout.LayoutParams(
176
- ViewGroup.LayoutParams.MATCH_PARENT, 0, 1f
177
- ));
178
-
179
- root.addView(header);
180
- root.addView(webView);
181
-
182
- dialog.setContentView(root);
183
- dialog.setCancelable(true);
184
- dialog.setOnCancelListener(d -> {
185
- if (!alreadyRedirected && listener != null) listener.onCancelled();
186
- });
187
- dialog.show();
188
-
189
- webView.loadUrl(url);
190
- }
191
-
192
- public void dismiss() {
193
- try {
194
- if (webView != null) {
195
- webView.stopLoading();
196
- webView.destroy();
197
- webView = null;
198
- }
199
- if (dialog != null && dialog.isShowing()) {
200
- dialog.dismiss();
201
- }
202
- dialog = null;
203
- } catch (Exception ignored) {}
204
- }
158
+ final String finalBody = (body != null) ? body : "";
159
+ android.util.Log.d("SSOWebView",
160
+ "body len=" + finalBody.length() +
161
+ " preview=" + finalBody.substring(
162
+ 0, Math.min(120, finalBody.length())));
163
+
164
+ /* FIX: gunakan outer class reference */
165
+ activity.runOnUiThread(() -> SSOWebView.this.dismiss());
166
+
167
+ if (listener != null)
168
+ listener.onRedirectIntercepted(
169
+ finalUrl, finalCode, finalState, finalBody);
170
+ }
171
+ );
172
+ }
173
+ }, 150);
174
+ }
175
+
176
+ private void dismiss() {
177
+ SSOWebView.this.dismiss();
178
+ }
179
+ });
180
+
181
+ webView.setLayoutParams(new LinearLayout.LayoutParams(
182
+ ViewGroup.LayoutParams.MATCH_PARENT, 0, 1 f));
183
+
184
+ root.addView(header);
185
+ root.addView(webView);
186
+
187
+ dialog.setContentView(root);
188
+ dialog.setCancelable(true);
189
+ dialog.setOnCancelListener(d -> {
190
+ if (!alreadyRedirected && listener != null)
191
+ listener.onCancelled();
192
+ });
193
+ dialog.show();
194
+
195
+ webView.loadUrl(url);
196
+ }
197
+
198
+ public void dismiss() {
199
+ try {
200
+ if (webView != null) {
201
+ webView.stopLoading();
202
+ webView.destroy();
203
+ webView = null;
204
+ }
205
+ if (dialog != null && dialog.isShowing()) {
206
+ dialog.dismiss();
207
+ }
208
+ dialog = null;
209
+ } catch (Exception ignored) {}
210
+ }
205
211
  }
@@ -33,12 +33,13 @@ public class SSOWebViewPlugin extends Plugin {
33
33
  title,
34
34
  new SSOWebView.Listener() {
35
35
  @Override
36
- public void onRedirectIntercepted(String u, String code, String state, String body) {
36
+ public void onRedirectIntercepted(String u, String code,
37
+ String state, String body) {
37
38
  JSObject ret = new JSObject();
38
39
  ret.put("url", u);
39
40
  ret.put("code", code);
40
41
  ret.put("state", state);
41
- ret.put("body", body);
42
+ ret.put("body", body); // ← TAMBAHAN
42
43
  notifyListeners("ssoRedirect", ret);
43
44
  }
44
45
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capacitor-sso-webview",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "SSO WebView with URL intercept",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",