@@ -27,14 +27,21 @@ class HubManaged {
2727 data : {
2828 email : this . _submitData . email
2929 }
30- } ) . done ( _ => {
30+ } ) . done ( response => {
31+ // Auto-populate subdomain only if it's a company email
32+ if ( response . isCompanyEmail ) {
33+ this . _submitData . subdomain = emailToSubdomain ( this . _submitData . email ) ;
34+ } else {
35+ // Clear subdomain for non-company emails (freemail, etc.)
36+ this . _submitData . subdomain = '' ;
37+ }
3138 this . onValidationSucceeded ( ) ;
3239 } ) . fail ( xhr => {
3340 this . onValidationFailed ( xhr . responseJSON ?. message || 'Validating email failed.' ) ;
3441 } ) ;
3542 }
3643
37- validateTeamAndSubdomain ( ) {
44+ validateSubdomain ( ) {
3845 if ( ! $ ( this . _form ) [ 0 ] . checkValidity ( ) ) {
3946 $ ( this . _form ) . find ( ':input' ) . addClass ( 'show-invalid' ) ;
4047 this . _feedbackData . errorMessage = 'Please fill in all required fields.' ;
@@ -47,13 +54,12 @@ class HubManaged {
4754 url : VALIDATE_HUB_MANAGED_REQUEST_URL ,
4855 type : 'GET' ,
4956 data : {
50- team : this . _submitData . team ,
5157 subdomain : this . _submitData . subdomain
5258 }
5359 } ) . done ( _ => {
5460 this . onValidationSucceeded ( ) ;
5561 } ) . fail ( xhr => {
56- this . onValidationFailed ( xhr . responseJSON ?. message || 'Validating team and subdomain failed.' ) ;
62+ this . onValidationFailed ( xhr . responseJSON ?. message || 'Validating subdomain failed.' ) ;
5763 } ) ;
5864 }
5965
@@ -153,6 +159,73 @@ function teamToSubdomain(team) {
153159 return subdomain ;
154160}
155161
162+ function emailToSubdomain ( email ) {
163+ if ( ! email || ! email . includes ( '@' ) ) {
164+ return '' ;
165+ }
166+
167+ // Extract domain from email
168+ const domain = email . split ( '@' ) [ 1 ] . toLowerCase ( ) ;
169+
170+ // Extract subdomain from email domain
171+ const domainParts = domain . split ( '.' ) ;
172+
173+ // For domains with multiple levels, try to find the most meaningful part
174+ let subdomain = '' ;
175+
176+ if ( domainParts . length >= 2 ) {
177+ // Common TLDs and country codes to ignore
178+ const tlds = [ 'com' , 'org' , 'net' , 'edu' , 'gov' , 'mil' , 'co' , 'io' , 'me' , 'info' , 'biz' ] ;
179+ const countryCodes = [ 'de' , 'uk' , 'fr' , 'es' , 'it' , 'nl' , 'at' , 'ch' , 'us' , 'ca' , 'au' , 'jp' , 'cn' , 'in' , 'br' ] ;
180+
181+ // For academic domains (containing .edu, .ac, .edu.*, .ac.*)
182+ if ( domain . includes ( '.edu' ) || domain . includes ( '.ac.' ) ) {
183+ // Try to find the institution name (usually right before .edu/.ac)
184+ for ( let i = domainParts . length - 3 ; i >= 0 ; i -- ) {
185+ if ( ! tlds . includes ( domainParts [ i ] ) && ! countryCodes . includes ( domainParts [ i ] ) ) {
186+ subdomain = domainParts [ i ] ;
187+ break ;
188+ }
189+ }
190+ }
191+
192+ // If no academic pattern or no match found, use heuristics
193+ if ( ! subdomain ) {
194+ // Skip the last part (TLD) and country code if present
195+ let skipParts = 1 ;
196+ if ( domainParts . length > 2 && countryCodes . includes ( domainParts [ domainParts . length - 1 ] ) ) {
197+ skipParts = 2 ;
198+ }
199+
200+ // Look for the most meaningful part (skip common subdomains)
201+ const commonSubdomains = [ 'www' , 'mail' , 'email' , 'smtp' , 'pop' , 'imap' , 'webmail' , 'smail' ] ;
202+ for ( let i = domainParts . length - skipParts - 1 ; i >= 0 ; i -- ) {
203+ if ( ! commonSubdomains . includes ( domainParts [ i ] ) ) {
204+ subdomain = domainParts [ i ] ;
205+ break ;
206+ }
207+ }
208+
209+ // If all parts are common subdomains, just use the first part
210+ if ( ! subdomain && domainParts . length > skipParts ) {
211+ subdomain = domainParts [ 0 ] ;
212+ }
213+ }
214+
215+ // Clean up the subdomain to match the allowed pattern
216+ subdomain = subdomain . replace ( / [ ^ a - z 0 - 9 - ] / g, '-' ) ;
217+ subdomain = subdomain . replace ( / - + / g, '-' ) ;
218+ subdomain = subdomain . replace ( / ^ - + | - + $ / g, '' ) ;
219+
220+ // Ensure it's not empty and within length limits
221+ if ( subdomain && subdomain . length <= 63 ) {
222+ return subdomain ;
223+ }
224+ }
225+
226+ return '' ;
227+ }
228+
156229function subdomainToURL ( subdomain ) {
157230 return `https://${ subdomain } .cryptomator.cloud` ;
158231}
0 commit comments