@micha.bigler/ui-core-micha 2.1.18 → 2.1.20

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.
@@ -36,7 +36,10 @@ export function SecurityComponent({ fromRecovery = false, fromWeakLogin = false,
36
36
  setMessageKey(null);
37
37
  setErrorKey(null);
38
38
  try {
39
- await startSocialLogin(provider);
39
+ await startSocialLogin(provider, {
40
+ process: 'connect',
41
+ callbackUrl: `${window.location.origin}/account?tab=security`,
42
+ });
40
43
  }
41
44
  catch (err) {
42
45
  setErrorKey(err.code || 'Auth.SOCIAL_LOGIN_FAILED');
@@ -16,7 +16,7 @@ import { MfaLoginComponent } from '../components/MfaLoginComponent';
16
16
  export function LoginPage() {
17
17
  const navigate = useNavigate();
18
18
  const location = useLocation();
19
- const { login, authMethods } = useContext(AuthContext);
19
+ const { user, loading, login, authMethods } = useContext(AuthContext);
20
20
  const { t } = useTranslation();
21
21
  // State
22
22
  const [step, setStep] = useState('credentials'); // 'credentials' | 'mfa'
@@ -38,6 +38,18 @@ export function LoginPage() {
38
38
  setErrorKey('Auth.SOCIAL_LOGIN_FAILED');
39
39
  }
40
40
  }, [location.search]);
41
+ useEffect(() => {
42
+ var _a;
43
+ if (loading || !user)
44
+ return;
45
+ const requiresExtra = ((_a = user.security_state) === null || _a === void 0 ? void 0 : _a.requires_additional_security) === true;
46
+ if (requiresExtra) {
47
+ navigate('/account?tab=security&from=weak_login', { replace: true });
48
+ }
49
+ else {
50
+ navigate('/', { replace: true });
51
+ }
52
+ }, [loading, user, navigate]);
41
53
  // --- Helper: Central Success Logic ---
42
54
  const handleLoginSuccess = (user) => {
43
55
  var _a;
@@ -107,14 +107,14 @@ function getCsrfTokenFromCookie() {
107
107
  const match = document.cookie.match(/(?:^|; )csrftoken=([^;]+)/);
108
108
  return match ? decodeURIComponent(match[1]) : null;
109
109
  }
110
- function submitSocialRedirectForm({ provider, callbackUrl, csrfToken }) {
110
+ function submitSocialRedirectForm({ provider, callbackUrl, csrfToken, process }) {
111
111
  const form = document.createElement('form');
112
112
  form.method = 'POST';
113
113
  form.action = `${HEADLESS_BASE}/auth/provider/redirect`;
114
114
  form.style.display = 'none';
115
115
  const fields = {
116
116
  provider,
117
- process: 'login',
117
+ process,
118
118
  callback_url: callbackUrl,
119
119
  csrfmiddlewaretoken: csrfToken,
120
120
  };
@@ -128,7 +128,7 @@ function submitSocialRedirectForm({ provider, callbackUrl, csrfToken }) {
128
128
  document.body.appendChild(form);
129
129
  form.submit();
130
130
  }
131
- export async function startSocialLogin(provider) {
131
+ export async function startSocialLogin(provider, options = {}) {
132
132
  if (typeof window === 'undefined') {
133
133
  throw normaliseApiError(new Error('Auth.SOCIAL_LOGIN_NOT_IN_BROWSER'), 'Auth.SOCIAL_LOGIN_NOT_IN_BROWSER');
134
134
  }
@@ -143,6 +143,11 @@ export async function startSocialLogin(provider) {
143
143
  if (!csrfToken) {
144
144
  throw normaliseApiError(new Error('Auth.SOCIAL_LOGIN_FAILED'), 'Auth.SOCIAL_LOGIN_FAILED');
145
145
  }
146
- const callbackUrl = `${window.location.origin}/login`;
147
- submitSocialRedirectForm({ provider, callbackUrl, csrfToken });
146
+ const process = options.process === 'connect' ? 'connect' : 'login';
147
+ const originUrl = new URL(window.location.origin);
148
+ if (originUrl.hostname.startsWith('www.')) {
149
+ originUrl.hostname = originUrl.hostname.slice(4);
150
+ }
151
+ const callbackUrl = options.callbackUrl || `${originUrl.origin}/login`;
152
+ submitSocialRedirectForm({ provider, callbackUrl, csrfToken, process });
148
153
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@micha.bigler/ui-core-micha",
3
- "version": "2.1.18",
3
+ "version": "2.1.20",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.js",
6
6
  "private": false,
@@ -52,7 +52,10 @@ export function SecurityComponent({
52
52
  setMessageKey(null);
53
53
  setErrorKey(null);
54
54
  try {
55
- await startSocialLogin(provider);
55
+ await startSocialLogin(provider, {
56
+ process: 'connect',
57
+ callbackUrl: `${window.location.origin}/account?tab=security`,
58
+ });
56
59
  } catch (err) {
57
60
  setErrorKey(err.code || 'Auth.SOCIAL_LOGIN_FAILED');
58
61
  }
@@ -19,7 +19,7 @@ import { MfaLoginComponent } from '../components/MfaLoginComponent';
19
19
  export function LoginPage() {
20
20
  const navigate = useNavigate();
21
21
  const location = useLocation();
22
- const { login, authMethods } = useContext(AuthContext);
22
+ const { user, loading, login, authMethods } = useContext(AuthContext);
23
23
  const { t } = useTranslation();
24
24
 
25
25
  // State
@@ -47,6 +47,17 @@ export function LoginPage() {
47
47
  }
48
48
  }, [location.search]);
49
49
 
50
+ useEffect(() => {
51
+ if (loading || !user) return;
52
+
53
+ const requiresExtra = user.security_state?.requires_additional_security === true;
54
+ if (requiresExtra) {
55
+ navigate('/account?tab=security&from=weak_login', { replace: true });
56
+ } else {
57
+ navigate('/', { replace: true });
58
+ }
59
+ }, [loading, user, navigate]);
60
+
50
61
  // --- Helper: Central Success Logic ---
51
62
  const handleLoginSuccess = (user) => {
52
63
  login(user); // Update Context
@@ -141,7 +141,7 @@ function getCsrfTokenFromCookie() {
141
141
  return match ? decodeURIComponent(match[1]) : null;
142
142
  }
143
143
 
144
- function submitSocialRedirectForm({ provider, callbackUrl, csrfToken }) {
144
+ function submitSocialRedirectForm({ provider, callbackUrl, csrfToken, process }) {
145
145
  const form = document.createElement('form');
146
146
  form.method = 'POST';
147
147
  form.action = `${HEADLESS_BASE}/auth/provider/redirect`;
@@ -149,7 +149,7 @@ function submitSocialRedirectForm({ provider, callbackUrl, csrfToken }) {
149
149
 
150
150
  const fields = {
151
151
  provider,
152
- process: 'login',
152
+ process,
153
153
  callback_url: callbackUrl,
154
154
  csrfmiddlewaretoken: csrfToken,
155
155
  };
@@ -166,7 +166,7 @@ function submitSocialRedirectForm({ provider, callbackUrl, csrfToken }) {
166
166
  form.submit();
167
167
  }
168
168
 
169
- export async function startSocialLogin(provider) {
169
+ export async function startSocialLogin(provider, options = {}) {
170
170
  if (typeof window === 'undefined') {
171
171
  throw normaliseApiError(
172
172
  new Error('Auth.SOCIAL_LOGIN_NOT_IN_BROWSER'),
@@ -189,6 +189,11 @@ export async function startSocialLogin(provider) {
189
189
  );
190
190
  }
191
191
 
192
- const callbackUrl = `${window.location.origin}/login`;
193
- submitSocialRedirectForm({ provider, callbackUrl, csrfToken });
192
+ const process = options.process === 'connect' ? 'connect' : 'login';
193
+ const originUrl = new URL(window.location.origin);
194
+ if (originUrl.hostname.startsWith('www.')) {
195
+ originUrl.hostname = originUrl.hostname.slice(4);
196
+ }
197
+ const callbackUrl = options.callbackUrl || `${originUrl.origin}/login`;
198
+ submitSocialRedirectForm({ provider, callbackUrl, csrfToken, process });
194
199
  }