@@ -3,6 +3,7 @@ import { Encryption } from "../models/encryption";
33import * as CryptoJS from "crypto-js" ;
44import { OTPType , OTPAlgorithm } from "../models/otp" ;
55import { ActionContext } from "vuex" ;
6+ import { getSiteName , getMatchedEntriesHash } from "../utils" ;
67
78export class Accounts implements Module {
89 async getModule ( ) {
@@ -22,7 +23,7 @@ export class Accounts implements Module {
2223 sectorOffset : 0 , // Offset in seconds for animations
2324 second : 0 , // Offset in seconds for math
2425 filter : true ,
25- siteName : await this . getSiteName ( ) ,
26+ siteName : await getSiteName ( ) ,
2627 showSearch : false ,
2728 exportData : await EntryStorage . getExport ( entries ) ,
2829 exportEncData : await EntryStorage . getExport ( entries , true ) ,
@@ -41,7 +42,7 @@ export class Accounts implements Module {
4142 ) ;
4243 } ,
4344 matchedEntries : ( state : AccountsState ) => {
44- return this . matchedEntries ( state . siteName , state . entries ) ;
45+ return getMatchedEntriesHash ( state . siteName , state . entries ) ;
4546 } ,
4647 currentlyEncrypted ( state : AccountsState ) {
4748 for ( const entry of state . entries ) {
@@ -513,82 +514,6 @@ export class Accounts implements Module {
513514 } ;
514515 }
515516
516- private async getSiteName ( ) {
517- return new Promise ( ( resolve : ( value : Array < string | null > ) => void ) => {
518- chrome . tabs . query ( { active : true , lastFocusedWindow : true } , ( tabs ) => {
519- const tab = tabs [ 0 ] ;
520- const query = new URLSearchParams (
521- document . location . search . substring ( 1 )
522- ) ;
523-
524- let title : string | null ;
525- let url : string | null ;
526- const titleFromQuery = query . get ( "title" ) ;
527- const urlFromQuery = query . get ( "url" ) ;
528-
529- if ( titleFromQuery && urlFromQuery ) {
530- title = decodeURIComponent ( titleFromQuery ) ;
531- url = decodeURIComponent ( urlFromQuery ) ;
532- } else {
533- if ( ! tab ) {
534- return resolve ( [ null , null ] ) ;
535- }
536-
537- title = tab . title ?. replace ( / [ ^ a - z 0 - 9 ] / gi, "" ) . toLowerCase ( ) ?? null ;
538- url = tab . url ?? null ;
539- }
540-
541- if ( ! url ) {
542- return resolve ( [ title , null ] ) ;
543- }
544-
545- const urlParser = new URL ( url ) ;
546- const hostname = urlParser . hostname ; // it's always lower case
547-
548- // try to parse name from hostname
549- // i.e. hostname is www.example.com
550- // name should be example
551- let nameFromDomain = "" ;
552-
553- // ip address
554- if ( / ^ \d + \. \d + \. \d + \. \d + $ / . test ( hostname ) ) {
555- nameFromDomain = hostname ;
556- }
557-
558- // local network
559- if ( hostname . indexOf ( "." ) === - 1 ) {
560- nameFromDomain = hostname ;
561- }
562-
563- const hostLevelUnits = hostname . split ( "." ) ;
564-
565- if ( hostLevelUnits . length === 2 ) {
566- nameFromDomain = hostLevelUnits [ 0 ] ;
567- }
568-
569- // www.example.com
570- // example.com.cn
571- if ( hostLevelUnits . length > 2 ) {
572- // example.com.cn
573- if (
574- [ "com" , "net" , "org" , "edu" , "gov" , "co" ] . indexOf (
575- hostLevelUnits [ hostLevelUnits . length - 2 ]
576- ) !== - 1
577- ) {
578- nameFromDomain = hostLevelUnits [ hostLevelUnits . length - 3 ] ;
579- } else {
580- // www.example.com
581- nameFromDomain = hostLevelUnits [ hostLevelUnits . length - 2 ] ;
582- }
583- }
584-
585- nameFromDomain = nameFromDomain . replace ( / - / g, "" ) . toLowerCase ( ) ;
586-
587- return resolve ( [ title , nameFromDomain , hostname ] ) ;
588- } ) ;
589- } ) ;
590- }
591-
592517 private getCachedPassphrase ( ) {
593518 return new Promise ( ( resolve : ( value : string ) => void ) => {
594519 chrome . runtime . sendMessage (
@@ -604,62 +529,4 @@ export class Accounts implements Module {
604529 const otpEntries = await EntryStorage . get ( ) ;
605530 return otpEntries ;
606531 }
607-
608- private matchedEntries (
609- siteName : Array < string | null > ,
610- entries : OTPEntryInterface [ ]
611- ) {
612- if ( siteName . length < 2 ) {
613- return false ;
614- }
615-
616- const matched = [ ] ;
617-
618- for ( const entry of entries ) {
619- if ( this . isMatchedEntry ( siteName , entry ) ) {
620- matched . push ( entry . hash ) ;
621- }
622- }
623-
624- return matched ;
625- }
626-
627- private isMatchedEntry (
628- siteName : Array < string | null > ,
629- entry : OTPEntryInterface
630- ) {
631- if ( ! entry . issuer ) {
632- return false ;
633- }
634-
635- const issuerHostMatches = entry . issuer . split ( "::" ) ;
636- const issuer = issuerHostMatches [ 0 ]
637- . replace ( / [ ^ 0 - 9 a - z ] / gi, "" )
638- . toLowerCase ( ) ;
639-
640- if ( ! issuer ) {
641- return false ;
642- }
643-
644- const siteTitle = siteName [ 0 ] || "" ;
645- const siteNameFromHost = siteName [ 1 ] || "" ;
646- const siteHost = siteName [ 2 ] || "" ;
647-
648- if ( issuerHostMatches . length > 1 ) {
649- if ( siteHost && siteHost . indexOf ( issuerHostMatches [ 1 ] ) !== - 1 ) {
650- return true ;
651- }
652- }
653- // site title should be more detailed
654- // so we use siteTitle.indexOf(issuer)
655- if ( siteTitle && siteTitle . indexOf ( issuer ) !== - 1 ) {
656- return true ;
657- }
658-
659- if ( siteNameFromHost && issuer . indexOf ( siteNameFromHost ) !== - 1 ) {
660- return true ;
661- }
662-
663- return false ;
664- }
665532}
0 commit comments