diff --git a/lib/utils/reserved-users.js b/lib/utils/reserved-users.js deleted file mode 100644 index d96ed7348..000000000 --- a/lib/utils/reserved-users.js +++ /dev/null @@ -1,2236 +0,0 @@ -// @flow - -const reservedUsernamesSet: $ReadOnlySet = new Set([ - //Additional Reserved Keywords - 'Comm', - 'dapp-tools', - 'dapp_tools', - 'ethers-js', - 'ethers_js', - 'ganache-cli', - 'ganache_cli', - 'hardhat', - 'Mod', - 'Moderator', - 'solidity', - 'truffle', - 'web3', - 'web3modal', - - //Reserved Usernames List - //https://github.com/shouldbee/reserved-usernames - '0', - '12', - '49', - '478', - '1hive', - 'aave', - 'agoraspace', - 'aladdindao', - 'alchemistdao', - 'allships', - 'ampled', - 'angeldao', - 'aragon', - 'badgerdao', - 'bankless', - 'bardao', - 'bayc', - 'beetsdao', - 'braintrust', - 'bright', - 'brightid', - 'brightmomentsgallery', - 'brrdao', - 'cabindao', - 'canudao', - 'cedge', - 'clip', - 'closerdao', - 'coinvise', - 'collab-land', - 'collab_land', - 'colony', - 'comp', - 'compound', - 'coordinape', - 'cre8club', - 'crisisdao', - 'cspdao', - 'daohaus', - 'daosquare', - 'daostack', - 'darkstardao', - 'decred', - 'developerdao', - 'devs', - 'dfdao', - 'dinnerdao', - 'dinogangz', - 'discodao', - 'distributed-town', - 'distributed_town', - 'divineroles', - 'dopewarsdao', - 'dorg', - 'duckdao', - 'dxdao', - 'edendao', - 'elektradao', - 'ethernautdao', - 'etherscan', - 'evewealth', - 'ff', - 'fiatluxdao', - 'fingerprints', - 'fireeyes', - 'flamingodao', - 'forefront', - 'freecompany', - 'friendswithbenefits', - 'fwb', - 'gardens', - 'gcr', - 'genezisbiohacking', - 'genre', - 'geometrydao', - 'gitcoin', - 'gnosis', - 'gnosissafe', - 'gorn', - 'gornhegemonydao', - 'gremlins', - 'guildhall', - 'habitat', - 'heatdao', - 'herstorydao', - 'honeydao', - 'idlefinance', - 'indexcoop', - 'insuredao', - 'jennydao', - 'joystream', - 'jumperdao', - 'keeperdao', - 'kleoverse', - 'komorebicollective', - 'krause', - 'krausehouse', - 'learndao', - 'leavingrecords', - 'lex', - 'lexdao', - 'llama', - 'lovesocietydao', - 'lurkerdao', - 'magnetdao', - 'makerdao', - 'maodao', - 'maskdao', - 'meebitsdao', - 'meritcircle', - 'metacartel', - 'metafam', - 'metagammadelta', - 'metamask', - 'metaversedao', - 'minty', - 'mirror-xyz', - 'mirror_xyz', - 'mirrorclubdao', - 'molochdao', - 'moonshotcollective', - 'moshdao', - 'muse0', - 'nebo', - 'neptunedao', - 'nfdao', - 'nounsdao', - 'olympusdao', - 'opendao', - 'opensea', - 'opolis', - 'orcaprotocol', - 'pacdao', - 'paperclip', - 'parcel', - 'party', - 'partydao', - 'peerion', - 'phlotedao', - 'physicalanddigitalartaficionados', - 'pizzadao', - 'pleasrdao', - 'pokemontrainersclub', - 'prints', - 'proofofhumanity', - 'prosperdao', - 'proteindao', - 'psydao', - 'rabbithole', - 'raidguild', - 'rainbowwallet', - 'raribledao', - 'readyplayerdao', - 'reddao', - 'ref', - 'retokendao', - 'ribondao', - 'rumblekong', - 'sarcophagus', - 'scribedao', - 'seedclub', - 'sharkdao', - 'shinydao', - 'snapshot', - 'snx', - 'sourcecred', - 'spork', - 'sporkdao', - 'sputnik-fund', - 'sputnik_fund', - 'squaddao', - 'squig', - 'squiggle', - 'stack', - 'stackerventuresdao', - 'syndicate', - 'synthetix', - 'tally', - 'taodao', - 'tarascadao', - 'terrachess', - 'thelao', - 'thewipmeetup', - 'thugdao', - 'tinseldao', - 'tokenwalkdao', - 'tomomasterdao', - 'triforcedao', - 'trippy', - 'trojandao', - 'ultradao', - 'universitydao', - 'unlockdao', - 'vectordao', - 'viariodao', - 'vita', - 'vitadao', - 'walletconnect', - 'whalerdao', - 'whiskeypioneers', - 'yamdao', - 'yearn', - 'yfi', - 'ygg', - 'zouzoukwa', - - //Top Level Domains - //https://data.iana.org/TLD/tlds-alpha-by-domain.txt - 'aaa', - 'aarp', - 'abarth', - 'abb', - 'abbott', - 'abbvie', - 'abc', - 'able', - 'abogado', - 'abudhabi', - 'ac', - 'academy', - 'accenture', - 'accountant', - 'accountants', - 'aco', - 'actor', - 'ad', - 'adac', - 'ads', - 'adult', - 'ae', - 'aeg', - 'aero', - 'aetna', - 'af', - 'afamilycompany', - 'afl', - 'africa', - 'ag', - 'agakhan', - 'agency', - 'ai', - 'aig', - 'airbus', - 'airforce', - 'airtel', - 'akdn', - 'al', - 'alfaromeo', - 'alibaba', - 'alipay', - 'allfinanz', - 'allstate', - 'ally', - 'alsace', - 'alstom', - 'am', - 'amazon', - 'americanexpress', - 'americanfamily', - 'amex', - 'amfam', - 'amica', - 'amsterdam', - 'analytics', - 'android', - 'anquan', - 'anz', - 'ao', - 'aol', - 'apartments', - 'app', - 'apple', - 'aq', - 'aquarelle', - 'ar', - 'arab', - 'aramco', - 'archi', - 'army', - 'arpa', - 'art', - 'arte', - 'as', - 'asda', - 'asia', - 'associates', - 'at', - 'athleta', - 'attorney', - 'au', - 'auction', - 'audi', - 'audible', - 'audio', - 'auspost', - 'author', - 'auto', - 'autos', - 'avianca', - 'aw', - 'aws', - 'ax', - 'axa', - 'az', - 'azure', - 'ba', - 'baby', - 'baidu', - 'banamex', - 'bananarepublic', - 'band', - 'bank', - 'bar', - 'barcelona', - 'barclaycard', - 'barclays', - 'barefoot', - 'bargains', - 'baseball', - 'basketball', - 'bauhaus', - 'bayern', - 'bb', - 'bbc', - 'bbt', - 'bbva', - 'bcg', - 'bcn', - 'bd', - 'be', - 'beats', - 'beauty', - 'beer', - 'bentley', - 'berlin', - 'best', - 'bestbuy', - 'bet', - 'bf', - 'bg', - 'bh', - 'bharti', - 'bi', - 'bible', - 'bid', - 'bike', - 'bing', - 'bingo', - 'bio', - 'biz', - 'bj', - 'black', - 'blackfriday', - 'blockbuster', - 'blog', - 'bloomberg', - 'blue', - 'bm', - 'bms', - 'bmw', - 'bn', - 'bnpparibas', - 'bo', - 'boats', - 'boehringer', - 'bofa', - 'bom', - 'bond', - 'boo', - 'book', - 'booking', - 'bosch', - 'bostik', - 'boston', - 'bot', - 'boutique', - 'box', - 'br', - 'bradesco', - 'bridgestone', - 'broadway', - 'broker', - 'brother', - 'brussels', - 'bs', - 'bt', - 'budapest', - 'bugatti', - 'build', - 'builders', - 'business', - 'buy', - 'buzz', - 'bv', - 'bw', - 'by', - 'bz', - 'bzh', - 'ca', - 'cab', - 'cafe', - 'cal', - 'call', - 'calvinklein', - 'cam', - 'camera', - 'camp', - 'cancerresearch', - 'canon', - 'capetown', - 'capital', - 'capitalone', - 'car', - 'caravan', - 'cards', - 'care', - 'career', - 'careers', - 'cars', - 'casa', - 'case', - 'cash', - 'casino', - 'cat', - 'catering', - 'catholic', - 'cba', - 'cbn', - 'cbre', - 'cbs', - 'cc', - 'cd', - 'center', - 'ceo', - 'cern', - 'cf', - 'cfa', - 'cfd', - 'cg', - 'ch', - 'chanel', - 'channel', - 'charity', - 'chase', - 'chat', - 'cheap', - 'chintai', - 'christmas', - 'chrome', - 'church', - 'ci', - 'cipriani', - 'circle', - 'cisco', - 'citadel', - 'citi', - 'citic', - 'city', - 'cityeats', - 'ck', - 'cl', - 'claims', - 'cleaning', - 'click', - 'clinic', - 'clinique', - 'clothing', - 'cloud', - 'club', - 'clubmed', - 'cm', - 'cn', - 'co', - 'coach', - 'codes', - 'coffee', - 'college', - 'cologne', - 'com', - 'comcast', - 'commbank', - 'community', - 'company', - 'compare', - 'computer', - 'comsec', - 'condos', - 'construction', - 'consulting', - 'contact', - 'contractors', - 'cooking', - 'cookingchannel', - 'cool', - 'coop', - 'corsica', - 'country', - 'coupon', - 'coupons', - 'courses', - 'cpa', - 'cr', - 'credit', - 'creditcard', - 'creditunion', - 'cricket', - 'crown', - 'crs', - 'cruise', - 'cruises', - 'csc', - 'cu', - 'cuisinella', - 'cv', - 'cw', - 'cx', - 'cy', - 'cymru', - 'cyou', - 'cz', - 'dabur', - 'dad', - 'dance', - 'data', - 'date', - 'dating', - 'datsun', - 'day', - 'dclk', - 'dds', - 'de', - 'deal', - 'dealer', - 'deals', - 'degree', - 'delivery', - 'dell', - 'deloitte', - 'delta', - 'democrat', - 'dental', - 'dentist', - 'desi', - 'design', - 'dev', - 'dhl', - 'diamonds', - 'diet', - 'digital', - 'direct', - 'directory', - 'discount', - 'discover', - 'dish', - 'diy', - 'dj', - 'dk', - 'dm', - 'dnp', - 'do', - 'docs', - 'doctor', - 'dog', - 'domains', - 'dot', - 'download', - 'drive', - 'dtv', - 'dubai', - 'duck', - 'dunlop', - 'dupont', - 'durban', - 'dvag', - 'dvr', - 'dz', - 'earth', - 'eat', - 'ec', - 'eco', - 'edeka', - 'edu', - 'education', - 'ee', - 'eg', - 'email', - 'emerck', - 'energy', - 'engineer', - 'engineering', - 'enterprises', - 'epson', - 'equipment', - 'er', - 'ericsson', - 'erni', - 'es', - 'esq', - 'estate', - 'et', - 'etisalat', - 'eu', - 'eurovision', - 'eus', - 'events', - 'exchange', - 'expert', - 'exposed', - 'express', - 'extraspace', - 'fage', - 'fail', - 'fairwinds', - 'faith', - 'family', - 'fan', - 'fans', - 'farm', - 'farmers', - 'fashion', - 'fast', - 'fedex', - 'feedback', - 'ferrari', - 'ferrero', - 'fi', - 'fiat', - 'fidelity', - 'fido', - 'film', - 'final', - 'finance', - 'financial', - 'fire', - 'firestone', - 'firmdale', - 'fish', - 'fishing', - 'fit', - 'fitness', - 'fj', - 'fk', - 'flickr', - 'flights', - 'flir', - 'florist', - 'flowers', - 'fly', - 'fm', - 'fo', - 'foo', - 'food', - 'foodnetwork', - 'football', - 'ford', - 'forex', - 'forsale', - 'forum', - 'foundation', - 'fox', - 'fr', - 'free', - 'fresenius', - 'frl', - 'frogans', - 'frontdoor', - 'frontier', - 'ftr', - 'fujitsu', - 'fun', - 'fund', - 'furniture', - 'futbol', - 'fyi', - 'ga', - 'gal', - 'gallery', - 'gallo', - 'gallup', - 'game', - 'games', - 'gap', - 'garden', - 'gay', - 'gb', - 'gbiz', - 'gd', - 'gdn', - 'ge', - 'gea', - 'gent', - 'genting', - 'george', - 'gf', - 'gg', - 'ggee', - 'gh', - 'gi', - 'gift', - 'gifts', - 'gives', - 'giving', - 'gl', - 'glade', - 'glass', - 'gle', - 'global', - 'globo', - 'gm', - 'gmail', - 'gmbh', - 'gmo', - 'gmx', - 'gn', - 'godaddy', - 'gold', - 'goldpoint', - 'golf', - 'goo', - 'goodyear', - 'goog', - 'google', - 'gop', - 'got', - 'gov', - 'gp', - 'gq', - 'gr', - 'grainger', - 'graphics', - 'gratis', - 'green', - 'gripe', - 'grocery', - 'group', - 'gs', - 'gt', - 'gu', - 'guardian', - 'gucci', - 'guge', - 'guide', - 'guitars', - 'guru', - 'gw', - 'gy', - 'hair', - 'hamburg', - 'hangout', - 'haus', - 'hbo', - 'hdfc', - 'hdfcbank', - 'health', - 'healthcare', - 'help', - 'helsinki', - 'here', - 'hermes', - 'hgtv', - 'hiphop', - 'hisamitsu', - 'hitachi', - 'hiv', - 'hk', - 'hkt', - 'hm', - 'hn', - 'hockey', - 'holdings', - 'holiday', - 'homedepot', - 'homegoods', - 'homes', - 'homesense', - 'honda', - 'horse', - 'hospital', - 'host', - 'hosting', - 'hot', - 'hoteles', - 'hotels', - 'hotmail', - 'house', - 'how', - 'hr', - 'hsbc', - 'ht', - 'hu', - 'hughes', - 'hyatt', - 'hyundai', - 'ibm', - 'icbc', - 'ice', - 'icu', - 'id', - 'ie', - 'ieee', - 'ifm', - 'ikano', - 'il', - 'im', - 'imamat', - 'imdb', - 'immo', - 'immobilien', - 'in', - 'inc', - 'industries', - 'infiniti', - 'info', - 'ing', - 'ink', - 'institute', - 'insurance', - 'insure', - 'int', - 'international', - 'intuit', - 'investments', - 'io', - 'ipiranga', - 'iq', - 'ir', - 'irish', - 'is', - 'ismaili', - 'ist', - 'istanbul', - 'it', - 'itau', - 'itv', - 'jaguar', - 'java', - 'jcb', - 'je', - 'jeep', - 'jetzt', - 'jewelry', - 'jio', - 'jll', - 'jm', - 'jmp', - 'jnj', - 'jo', - 'jobs', - 'joburg', - 'jot', - 'joy', - 'jp', - 'jpmorgan', - 'jprs', - 'juegos', - 'juniper', - 'kaufen', - 'kddi', - 'ke', - 'kerryhotels', - 'kerrylogistics', - 'kerryproperties', - 'kfh', - 'kg', - 'kh', - 'ki', - 'kia', - 'kim', - 'kinder', - 'kindle', - 'kitchen', - 'kiwi', - 'km', - 'kn', - 'koeln', - 'komatsu', - 'kosher', - 'kp', - 'kpmg', - 'kpn', - 'kr', - 'krd', - 'kred', - 'kuokgroup', - 'kw', - 'ky', - 'kyoto', - 'kz', - 'la', - 'lacaixa', - 'lamborghini', - 'lamer', - 'lancaster', - 'lancia', - 'land', - 'landrover', - 'lanxess', - 'lasalle', - 'lat', - 'latino', - 'latrobe', - 'law', - 'lawyer', - 'lb', - 'lc', - 'lds', - 'lease', - 'leclerc', - 'lefrak', - 'legal', - 'lego', - 'lexus', - 'lgbt', - 'li', - 'lidl', - 'life', - 'lifeinsurance', - 'lifestyle', - 'lighting', - 'like', - 'lilly', - 'limited', - 'limo', - 'lincoln', - 'linde', - 'link', - 'lipsy', - 'live', - 'living', - 'lixil', - 'lk', - 'llc', - 'llp', - 'loan', - 'loans', - 'locker', - 'locus', - 'loft', - 'lol', - 'london', - 'lotte', - 'lotto', - 'love', - 'lpl', - 'lplfinancial', - 'lr', - 'ls', - 'lt', - 'ltd', - 'ltda', - 'lu', - 'lundbeck', - 'luxe', - 'luxury', - 'lv', - 'ly', - 'ma', - 'macys', - 'madrid', - 'maif', - 'maison', - 'makeup', - 'man', - 'management', - 'mango', - 'map', - 'market', - 'marketing', - 'markets', - 'marriott', - 'marshalls', - 'maserati', - 'mattel', - 'mba', - 'mc', - 'mckinsey', - 'md', - 'me', - 'med', - 'media', - 'meet', - 'melbourne', - 'meme', - 'memorial', - 'men', - 'menu', - 'merckmsd', - 'mg', - 'mh', - 'miami', - 'microsoft', - 'mil', - 'mini', - 'mint', - 'mit', - 'mitsubishi', - 'mk', - 'ml', - 'mlb', - 'mls', - 'mm', - 'mma', - 'mn', - 'mo', - 'mobi', - 'mobile', - 'moda', - 'moe', - 'moi', - 'mom', - 'monash', - 'money', - 'monster', - 'mormon', - 'mortgage', - 'moscow', - 'moto', - 'motorcycles', - 'mov', - 'movie', - 'mp', - 'mq', - 'mr', - 'ms', - 'msd', - 'mt', - 'mtn', - 'mtr', - 'mu', - 'museum', - 'music', - 'mutual', - 'mv', - 'mw', - 'mx', - 'my', - 'mz', - 'na', - 'nab', - 'nagoya', - 'name', - 'natura', - 'navy', - 'nba', - 'nc', - 'ne', - 'nec', - 'net', - 'netbank', - 'netflix', - 'network', - 'neustar', - 'new', - 'news', - 'next', - 'nextdirect', - 'nexus', - 'nf', - 'nfl', - 'ng', - 'ngo', - 'nhk', - 'ni', - 'nico', - 'nike', - 'nikon', - 'ninja', - 'nissan', - 'nissay', - 'nl', - 'no', - 'nokia', - 'northwesternmutual', - 'norton', - 'now', - 'nowruz', - 'nowtv', - 'np', - 'nr', - 'nra', - 'nrw', - 'ntt', - 'nu', - 'nyc', - 'nz', - 'obi', - 'observer', - 'off', - 'office', - 'okinawa', - 'olayan', - 'olayangroup', - 'oldnavy', - 'ollo', - 'om', - 'omega', - 'one', - 'ong', - 'onl', - 'online', - 'ooo', - 'open', - 'oracle', - 'orange', - 'org', - 'organic', - 'origins', - 'osaka', - 'otsuka', - 'ott', - 'ovh', - 'pa', - 'page', - 'panasonic', - 'paris', - 'pars', - 'partners', - 'parts', - 'passagens', - 'pay', - 'pccw', - 'pe', - 'pet', - 'pf', - 'pfizer', - 'pg', - 'ph', - 'pharmacy', - 'phd', - 'philips', - 'phone', - 'photo', - 'photography', - 'photos', - 'physio', - 'pics', - 'pictet', - 'pictures', - 'pid', - 'pin', - 'ping', - 'pink', - 'pioneer', - 'pizza', - 'pk', - 'pl', - 'place', - 'play', - 'playstation', - 'plumbing', - 'plus', - 'pm', - 'pn', - 'pnc', - 'pohl', - 'poker', - 'politie', - 'porn', - 'post', - 'pr', - 'pramerica', - 'praxi', - 'press', - 'prime', - 'pro', - 'prod', - 'productions', - 'prof', - 'progressive', - 'promo', - 'properties', - 'property', - 'protection', - 'pru', - 'prudential', - 'ps', - 'pt', - 'pub', - 'pw', - 'pwc', - 'py', - 'qa', - 'qpon', - 'quebec', - 'quest', - 'racing', - 'radio', - 'raid', - 're', - 'read', - 'realestate', - 'realtor', - 'realty', - 'recipes', - 'red', - 'redstone', - 'redumbrella', - 'rehab', - 'reise', - 'reisen', - 'reit', - 'reliance', - 'ren', - 'rent', - 'rentals', - 'repair', - 'report', - 'republican', - 'rest', - 'restaurant', - 'review', - 'reviews', - 'rexroth', - 'rich', - 'richardli', - 'ricoh', - 'ril', - 'rio', - 'rip', - 'ro', - 'rocher', - 'rocks', - 'rodeo', - 'rogers', - 'room', - 'rs', - 'rsvp', - 'ru', - 'rugby', - 'ruhr', - 'run', - 'rw', - 'rwe', - 'ryukyu', - 'sa', - 'saarland', - 'safe', - 'safety', - 'sakura', - 'sale', - 'salon', - 'samsclub', - 'samsung', - 'sandvik', - 'sandvikcoromant', - 'sanofi', - 'sap', - 'sarl', - 'sas', - 'save', - 'saxo', - 'sb', - 'sbi', - 'sbs', - 'sc', - 'sca', - 'scb', - 'schaeffler', - 'schmidt', - 'scholarships', - 'school', - 'schule', - 'schwarz', - 'science', - 'scjohnson', - 'scot', - 'sd', - 'se', - 'search', - 'seat', - 'secure', - 'security', - 'seek', - 'select', - 'sener', - 'services', - 'ses', - 'seven', - 'sew', - 'sex', - 'sexy', - 'sfr', - 'sg', - 'sh', - 'shangrila', - 'sharp', - 'shaw', - 'shell', - 'shia', - 'shiksha', - 'shoes', - 'shop', - 'shopping', - 'shouji', - 'show', - 'showtime', - 'si', - 'silk', - 'sina', - 'singles', - 'site', - 'sj', - 'sk', - 'ski', - 'skin', - 'sky', - 'skype', - 'sl', - 'sling', - 'sm', - 'smart', - 'smile', - 'sn', - 'sncf', - 'so', - 'soccer', - 'social', - 'softbank', - 'software', - 'sohu', - 'solar', - 'solutions', - 'song', - 'sony', - 'soy', - 'spa', - 'space', - 'sport', - 'spot', - 'sr', - 'srl', - 'ss', - 'st', - 'stada', - 'staples', - 'star', - 'statebank', - 'statefarm', - 'stc', - 'stcgroup', - 'stockholm', - 'storage', - 'store', - 'stream', - 'studio', - 'study', - 'style', - 'su', - 'sucks', - 'supplies', - 'supply', - 'support', - 'surf', - 'surgery', - 'suzuki', - 'sv', - 'swatch', - 'swiss', - 'sx', - 'sy', - 'sydney', - 'systems', - 'sz', - 'tab', - 'taipei', - 'talk', - 'taobao', - 'target', - 'tatamotors', - 'tatar', - 'tattoo', - 'tax', - 'taxi', - 'tc', - 'tci', - 'td', - 'tdk', - 'team', - 'tech', - 'technology', - 'tel', - 'temasek', - 'tennis', - 'teva', - 'tf', - 'tg', - 'th', - 'thd', - 'theater', - 'theatre', - 'tiaa', - 'tickets', - 'tienda', - 'tiffany', - 'tips', - 'tires', - 'tirol', - 'tj', - 'tjmaxx', - 'tjx', - 'tk', - 'tkmaxx', - 'tl', - 'tm', - 'tmall', - 'tn', - 'to', - 'today', - 'tokyo', - 'tools', - 'top', - 'toray', - 'toshiba', - 'total', - 'tours', - 'town', - 'toyota', - 'toys', - 'tr', - 'trade', - 'trading', - 'training', - 'travel', - 'travelchannel', - 'travelers', - 'travelersinsurance', - 'trust', - 'trv', - 'tt', - 'tube', - 'tui', - 'tunes', - 'tushu', - 'tv', - 'tvs', - 'tw', - 'tz', - 'ua', - 'ubank', - 'ubs', - 'ug', - 'uk', - 'unicom', - 'university', - 'uno', - 'uol', - 'ups', - 'us', - 'uy', - 'uz', - 'va', - 'vacations', - 'vana', - 'vanguard', - 'vc', - 've', - 'vegas', - 'ventures', - 'verisign', - 'versicherung', - 'vet', - 'vg', - 'vi', - 'viajes', - 'video', - 'vig', - 'viking', - 'villas', - 'vin', - 'vip', - 'virgin', - 'visa', - 'vision', - 'viva', - 'vivo', - 'vlaanderen', - 'vn', - 'vodka', - 'volkswagen', - 'volvo', - 'vote', - 'voting', - 'voto', - 'voyage', - 'vu', - 'vuelos', - 'wales', - 'walmart', - 'walter', - 'wang', - 'wanggou', - 'watch', - 'watches', - 'weather', - 'weatherchannel', - 'webcam', - 'weber', - 'website', - 'wed', - 'wedding', - 'weibo', - 'weir', - 'wf', - 'whoswho', - 'wien', - 'wiki', - 'williamhill', - 'win', - 'windows', - 'wine', - 'winners', - 'wme', - 'wolterskluwer', - 'woodside', - 'work', - 'works', - 'world', - 'wow', - 'ws', - 'wtc', - 'wtf', - 'xbox', - 'xerox', - 'xfinity', - 'xihuan', - 'xin', - 'xn--11b4c3d', - 'xn--1ck2e1b', - 'xn--1qqw23a', - 'xn--2scrj9c', - 'xn--30rr7y', - 'xn--3bst00m', - 'xn--3ds443g', - 'xn--3e0b707e', - 'xn--3hcrj9c', - 'xn--3pxu8k', - 'xn--42c2d9a', - 'xn--45br5cyl', - 'xn--45brj9c', - 'xn--45q11c', - 'xn--4dbrk0ce', - 'xn--4gbrim', - 'xn--54b7fta0cc', - 'xn--55qw42g', - 'xn--55qx5d', - 'xn--5su34j936bgsg', - 'xn--5tzm5g', - 'xn--6frz82g', - 'xn--6qq986b3xl', - 'xn--80adxhks', - 'xn--80ao21a', - 'xn--80aqecdr1a', - 'xn--80asehdb', - 'xn--80aswg', - 'xn--8y0a063a', - 'xn--90a3ac', - 'xn--90ae', - 'xn--90ais', - 'xn--9dbq2a', - 'xn--9et52u', - 'xn--9krt00a', - 'xn--b4w605ferd', - 'xn--bck1b9a5dre4c', - 'xn--c1avg', - 'xn--c2br7g', - 'xn--cck2b3b', - 'xn--cckwcxetd', - 'xn--cg4bki', - 'xn--clchc0ea0b2g2a9gcd', - 'xn--czr694b', - 'xn--czrs0t', - 'xn--czru2d', - 'xn--d1acj3b', - 'xn--d1alf', - 'xn--e1a4c', - 'xn--eckvdtc9d', - 'xn--efvy88h', - 'xn--fct429k', - 'xn--fhbei', - 'xn--fiq228c5hs', - 'xn--fiq64b', - 'xn--fiqs8s', - 'xn--fiqz9s', - 'xn--fjq720a', - 'xn--flw351e', - 'xn--fpcrj9c3d', - 'xn--fzc2c9e2c', - 'xn--fzys8d69uvgm', - 'xn--g2xx48c', - 'xn--gckr3f0f', - 'xn--gecrj9c', - 'xn--gk3at1e', - 'xn--h2breg3eve', - 'xn--h2brj9c', - 'xn--h2brj9c8c', - 'xn--hxt814e', - 'xn--i1b6b1a6a2e', - 'xn--imr513n', - 'xn--io0a7i', - 'xn--j1aef', - 'xn--j1amh', - 'xn--j6w193g', - 'xn--jlq480n2rg', - 'xn--jlq61u9w7b', - 'xn--jvr189m', - 'xn--kcrx77d1x4a', - 'xn--kprw13d', - 'xn--kpry57d', - 'xn--kput3i', - 'xn--l1acc', - 'xn--lgbbat1ad8j', - 'xn--mgb9awbf', - 'xn--mgba3a3ejt', - 'xn--mgba3a4f16a', - 'xn--mgba7c0bbn0a', - 'xn--mgbaakc7dvf', - 'xn--mgbaam7a8h', - 'xn--mgbab2bd', - 'xn--mgbah1a3hjkrd', - 'xn--mgbai9azgqp6j', - 'xn--mgbayh7gpa', - 'xn--mgbbh1a', - 'xn--mgbbh1a71e', - 'xn--mgbc0a9azcg', - 'xn--mgbca7dzdo', - 'xn--mgbcpq6gpa1a', - 'xn--mgberp4a5d4ar', - 'xn--mgbgu82a', - 'xn--mgbi4ecexp', - 'xn--mgbpl2fh', - 'xn--mgbt3dhd', - 'xn--mgbtx2b', - 'xn--mgbx4cd0ab', - 'xn--mix891f', - 'xn--mk1bu44c', - 'xn--mxtq1m', - 'xn--ngbc5azd', - 'xn--ngbe9e0a', - 'xn--ngbrx', - 'xn--node', - 'xn--nqv7f', - 'xn--nqv7fs00ema', - 'xn--nyqy26a', - 'xn--o3cw4h', - 'xn--ogbpf8fl', - 'xn--otu796d', - 'xn--p1acf', - 'xn--p1ai', - 'xn--pgbs0dh', - 'xn--pssy2u', - 'xn--q7ce6a', - 'xn--q9jyb4c', - 'xn--qcka1pmc', - 'xn--qxa6a', - 'xn--qxam', - 'xn--rhqv96g', - 'xn--rovu88b', - 'xn--rvc1e0am3e', - 'xn--s9brj9c', - 'xn--ses554g', - 'xn--t60b56a', - 'xn--tckwe', - 'xn--tiq49xqyj', - 'xn--unup4y', - 'xn--vermgensberater-ctb', - 'xn--vermgensberatung-pwb', - 'xn--vhquv', - 'xn--vuq861b', - 'xn--w4r85el8fhu5dnra', - 'xn--w4rs40l', - 'xn--wgbh1c', - 'xn--wgbl6a', - 'xn--xhq521b', - 'xn--xkc2al3hye2a', - 'xn--xkc2dl3a5ee0h', - 'xn--y9a3aq', - 'xn--yfro4i67o', - 'xn--ygbi2ammx', - 'xn--zfr164b', - - //DAO aggregate - //https://www.notion.so/commapp/DAO-aggregate-1539d5c849da4eec8f479e8f06d46c73 - 'xxx', - 'xyz', - 'yachts', - 'yahoo', - 'yamaxun', - 'yandex', - 'ye', - 'yodobashi', - 'yoga', - 'yokohama', - 'you', - 'youtube', - 'yt', - 'yun', - 'za', - 'zappos', - 'zara', - 'zero', - 'zip', - 'zm', - 'zone', - 'zuerich', - 'zw', - 'skiptocontent', - 'pullrequests', - 'issues', - 'marketplace', - 'explore', - '@andnasnd', - 'shouldbee/', - 'reserved-usernames', - 'public', - 'code', - 'issues4', - 'actions', - 'projects', - 'insights', - 'about', - 'access', - 'account', - 'accounts', - 'activate', - 'activities', - 'activity', - 'add', - 'address', - 'adm', - 'admin', - 'administration', - 'administrator', - 'advertising', - 'affiliate', - 'affiliates', - 'ajax', - 'all', - 'alpha', - 'analysis', - 'anon', - 'anonymous', - 'api', - 'apps', - 'archive', - 'archives', - 'article', - 'asct', - 'asset', - 'atom', - 'auth', - 'authentication', - 'avatar', - 'backup', - 'balancer-manager', - 'banner', - 'banners', - 'beta', - 'billing', - 'bin', - 'blogs', - 'board', - 'bookmark', - 'bots', - 'bug', - 'cache', - 'cadastro', - 'calendar', - 'campaign', - 'cancel', - 'captcha', - 'cart', - 'categories', - 'category', - 'cgi', - 'cgi-bin', - 'changelog', - 'check', - 'checking', - 'checkout', - 'client', - 'cliente', - 'clients', - 'codereview', - 'comercial', - 'comment', - 'comments', - 'communities', - 'compras', - 'config', - 'configuration', - 'connect', - 'contact-us', - 'contact_us', - 'contactus', - 'contest', - 'contribute', - 'corp', - 'create', - 'css', - 'dashboard', - 'db', - 'default', - 'delete', - 'demo', - 'designer', - 'destroy', - 'devel', - 'developer', - 'developers', - 'diagram', - 'diary', - 'dict', - 'dictionary', - 'die', - 'dir', - 'direct_messages', - 'dist', - 'doc', - 'documentation', - 'domain', - 'downloads', - 'ecommerce', - 'edit', - 'editor', - 'employment', - 'empty', - 'end', - 'enterprise', - 'entries', - 'entry', - 'error', - 'errors', - 'eval', - 'event', - 'everyone', - 'exit', - 'facebook', - 'faq', - 'favorite', - 'favorites', - 'feature', - 'features', - 'feed', - 'feeds', - 'file', - 'files', - 'first', - 'flash', - 'fleet', - 'fleets', - 'flog', - 'follow', - 'followers', - 'following', - 'forgot', - 'form', - 'forums', - 'founder', - 'friend', - 'friends', - 'ftp', - 'gadget', - 'gadgets', - 'get', - 'ghost', - 'gist', - 'github', - 'graph', - 'groups', - 'guest', - 'guests', - 'home', - 'homepage', - 'hostmaster', - 'hostname', - 'howto', - 'hpg', - 'html', - 'http', - 'httpd', - 'https', - 'i', - 'iamges', - 'icon', - 'icons', - 'idea', - 'ideas', - 'image', - 'images', - 'imap', - 'img', - 'index', - 'indice', - 'information', - 'inquiry', - 'instagram', - 'intranet', - 'invitations', - 'invite', - 'ipad', - 'iphone', - 'irc', - 'issue', - 'item', - 'items', - 'javascript', - 'job', - 'join', - 'js', - 'json', - 'jump', - 'knowledgebase', - 'language', - 'languages', - 'last', - 'ldap-status', - 'license', - 'links', - 'linux', - 'list', - 'lists', - 'log', - 'log-in', - 'log-out', - 'log_in', - 'log_out', - 'login', - 'logout', - 'logs', - 'm', - 'mac', - 'mail', - 'mail1', - 'mail2', - 'mail3', - 'mail4', - 'mail5', - 'mailer', - 'mailing', - 'maintenance', - 'manager', - 'manual', - 'maps', - 'master', - 'member', - 'members', - 'message', - 'messages', - 'messenger', - 'microblog', - 'microblogs', - 'mine', - 'mis', - 'mob', - 'movies', - 'mp3', - 'msg', - 'msn', - 'musicas', - 'mysql', - 'named', - 'nan', - 'navi', - 'navigation', - 'newsletter', - 'nick', - 'nickname', - 'notes', - 'noticias', - 'notification', - 'notifications', - 'notify', - 'ns', - 'ns1', - 'ns10', - 'ns2', - 'ns3', - 'ns4', - 'ns5', - 'ns6', - 'ns7', - 'ns8', - 'ns9', - 'null', - 'oauth', - 'oauth_clients', - 'offer', - 'offers', - 'official', - 'old', - 'openid', - 'operator', - 'order', - 'orders', - 'organization', - 'organizations', - 'overview', - 'owner', - 'owners', - 'pager', - 'pages', - 'panel', - 'password', - 'payment', - 'perl', - 'photoalbum', - 'php', - 'phpmyadmin', - 'phppgadmin', - 'phpredisadmin', - 'pic', - 'plan', - 'plans', - 'plugin', - 'plugins', - 'policy', - 'pop', - 'pop3', - 'popular', - 'portal', - 'postfix', - 'postmaster', - 'posts', - 'premium', - 'price', - 'pricing', - 'privacy', - 'privacy-policy', - 'privacy_policy', - 'privacypolicy', - 'private', - 'product', - 'products', - 'profile', - 'project', - 'purpose', - 'put', - 'python', - 'query', - 'random', - 'ranking', - 'readme', - 'recent', - 'recruit', - 'recruitment', - 'register', - 'registration', - 'release', - 'remove', - 'replies', - 'reports', - 'repositories', - 'repository', - 'req', - 'request', - 'requests', - 'reset', - 'roc', - 'root', - 'rss', - 'ruby', - 'rule', - 'sag', - 'sales', - 'sample', - 'samples', - 'script', - 'scripts', - 'self', - 'send', - 'server', - 'server-info', - 'server-status', - 'service', - 'session', - 'sessions', - 'setting', - 'settings', - 'setup', - 'share', - 'sign-in', - 'sign-up', - 'sign_in', - 'sign_up', - 'signin', - 'signout', - 'signup', - 'sitemap', - 'sites', - 'smartphone', - 'smtp', - 'soporte', - 'source', - 'spec', - 'special', - 'sql', - 'src', - 'ssh', - 'ssl', - 'ssladmin', - 'ssladministrator', - 'sslwebmaster', - 'staff', - 'stage', - 'staging', - 'start', - 'stat', - 'state', - 'static', - 'stats', - 'status', - 'stores', - 'stories', - 'styleguide', - 'stylesheet', - 'stylesheets', - 'subdomain', - 'subscribe', - 'subscriptions', - 'suporte', - 'svn', - 'swf', - 'sys', - 'sysadmin', - 'sysadministrator', - 'system', - 'tablet', - 'tablets', - 'tag', - 'task', - 'tasks', - 'teams', - 'telnet', - 'term', - 'terms', - 'terms-of-service', - 'terms_of_service', - 'termsofservice', - 'test', - 'test1', - 'test2', - 'test3', - 'teste', - 'testing', - 'tests', - 'theme', - 'themes', - 'thread', - 'threads', - 'tmp', - 'todo', - 'tool', - 'topic', - 'topics', - 'tos', - 'tour', - 'translations', - 'trends', - 'tutorial', - 'tux', - 'twitter', - 'undef', - 'unfollow', - 'unsubscribe', - 'update', - 'upload', - 'uploads', - 'url', - 'usage', - 'user', - 'username', - 'users', - 'usuario', - 'vendas', - 'ver', - 'version', - 'videos', - 'visitor', - 'web', - 'webhook', - 'webhooks', - 'webmail', - 'webmaster', - 'websites', - 'welcome', - 'widget', - 'widgets', - 'word', - 'workshop', - 'ww', - 'wws', - 'www', - 'www1', - 'www2', - 'www3', - 'www4', - 'www5', - 'www6', - 'www7', - 'wwws', - 'wwww', - 'xfn', - 'xml', - 'xmpp', - 'xpg', - 'yaml', - 'year', - 'yml', - 'yourdomain', - 'yourname', - 'yoursite', - 'yourusername', -]); - -export { reservedUsernamesSet }; diff --git a/native/account/register-panel.react.js b/native/account/register-panel.react.js index a99fa7a81..47156c244 100644 --- a/native/account/register-panel.react.js +++ b/native/account/register-panel.react.js @@ -1,476 +1,468 @@ // @flow import invariant from 'invariant'; import * as React from 'react'; import { Text, View, StyleSheet, Platform, Keyboard, Alert, Linking, } from 'react-native'; import Animated from 'react-native-reanimated'; import { registerActionTypes, register } from 'lib/actions/user-actions'; import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors'; import { validUsernameRegex } from 'lib/shared/account-utils'; import type { RegisterInfo, LogInExtraInfo, RegisterResult, LogInStartingPayload, } from 'lib/types/account-types'; import type { LoadingStatus } from 'lib/types/loading-types'; import { useServerCall, useDispatchActionPromise, type DispatchActionPromise, } from 'lib/utils/action-utils'; import SWMansionIcon from '../components/swmansion-icon.react'; import { NavContext } from '../navigation/navigation-context'; import { useSelector } from '../redux/redux-utils'; import { nativeLogInExtraInfoSelector } from '../selectors/account-selectors'; import type { KeyPressEvent } from '../types/react-native'; import { type StateContainer } from '../utils/state-container'; import { TextInput } from './modal-components.react'; import { setNativeCredentials } from './native-credentials'; import { PanelButton, Panel } from './panel-components.react'; export type RegisterState = { +usernameInputText: string, +passwordInputText: string, +confirmPasswordInputText: string, }; type BaseProps = { +setActiveAlert: (activeAlert: boolean) => void, +opacityValue: Animated.Node, +registerState: StateContainer, }; type Props = { ...BaseProps, // Redux state +loadingStatus: LoadingStatus, +logInExtraInfo: () => LogInExtraInfo, // Redux dispatch functions +dispatchActionPromise: DispatchActionPromise, // async functions that hit server APIs +register: (registerInfo: RegisterInfo) => Promise, }; type State = { +confirmPasswordFocused: boolean, }; class RegisterPanel extends React.PureComponent { state: State = { confirmPasswordFocused: false, }; usernameInput: ?TextInput; passwordInput: ?TextInput; confirmPasswordInput: ?TextInput; passwordBeingAutoFilled = false; render() { let confirmPasswordTextInputExtraProps; if ( Platform.OS !== 'ios' || this.state.confirmPasswordFocused || this.props.registerState.state.confirmPasswordInputText.length > 0 ) { confirmPasswordTextInputExtraProps = { secureTextEntry: true, textContentType: 'password', }; } let onPasswordKeyPress; if (Platform.OS === 'ios') { onPasswordKeyPress = this.onPasswordKeyPress; } /* eslint-disable react-native/no-raw-text */ const privatePolicyNotice = ( By signing up, you agree to our{' '} Terms {' & '} Privacy Policy . ); /* eslint-enable react-native/no-raw-text */ return ( {privatePolicyNotice} ); } usernameInputRef = (usernameInput: ?TextInput) => { this.usernameInput = usernameInput; }; passwordInputRef = (passwordInput: ?TextInput) => { this.passwordInput = passwordInput; }; confirmPasswordInputRef = (confirmPasswordInput: ?TextInput) => { this.confirmPasswordInput = confirmPasswordInput; }; focusUsernameInput = () => { invariant(this.usernameInput, 'ref should be set'); this.usernameInput.focus(); }; focusPasswordInput = () => { invariant(this.passwordInput, 'ref should be set'); this.passwordInput.focus(); }; focusConfirmPasswordInput = () => { invariant(this.confirmPasswordInput, 'ref should be set'); this.confirmPasswordInput.focus(); }; onTermsOfUsePressed = () => { Linking.openURL('https://comm.app/terms'); }; onPrivacyPolicyPressed = () => { Linking.openURL('https://comm.app/privacy'); }; onChangeUsernameInputText = (text: string) => { this.props.registerState.setState({ usernameInputText: text }); }; onChangePasswordInputText = (text: string) => { const stateUpdate = {}; stateUpdate.passwordInputText = text; if (this.passwordBeingAutoFilled) { this.passwordBeingAutoFilled = false; stateUpdate.confirmPasswordInputText = text; } this.props.registerState.setState(stateUpdate); }; onPasswordKeyPress = (event: KeyPressEvent) => { const { key } = event.nativeEvent; if ( key.length > 1 && key !== 'Backspace' && key !== 'Enter' && this.props.registerState.state.confirmPasswordInputText.length === 0 ) { this.passwordBeingAutoFilled = true; } }; onChangeConfirmPasswordInputText = (text: string) => { this.props.registerState.setState({ confirmPasswordInputText: text }); }; onConfirmPasswordFocus = () => { this.setState({ confirmPasswordFocused: true }); }; onSubmit = () => { this.props.setActiveAlert(true); if (this.props.registerState.state.passwordInputText === '') { Alert.alert( 'Empty password', 'Password cannot be empty', [{ text: 'OK', onPress: this.onPasswordAlertAcknowledged }], { cancelable: false }, ); } else if ( this.props.registerState.state.passwordInputText !== this.props.registerState.state.confirmPasswordInputText ) { Alert.alert( "Passwords don't match", 'Password fields must contain the same password', [{ text: 'OK', onPress: this.onPasswordAlertAcknowledged }], { cancelable: false }, ); } else if ( this.props.registerState.state.usernameInputText.search( validUsernameRegex, ) === -1 ) { Alert.alert( 'Invalid username', 'Usernames must be at least six characters long, start with either a ' + 'letter or a number, and may contain only letters, numbers, or the ' + 'characters “-” and “_”', [{ text: 'OK', onPress: this.onUsernameAlertAcknowledged }], { cancelable: false }, ); } else { Keyboard.dismiss(); const extraInfo = this.props.logInExtraInfo(); this.props.dispatchActionPromise( registerActionTypes, this.registerAction(extraInfo), undefined, ({ calendarQuery: extraInfo.calendarQuery }: LogInStartingPayload), ); } }; onPasswordAlertAcknowledged = () => { this.props.setActiveAlert(false); this.props.registerState.setState( { passwordInputText: '', confirmPasswordInputText: '', }, () => { invariant(this.passwordInput, 'ref should exist'); this.passwordInput.focus(); }, ); }; onUsernameAlertAcknowledged = () => { this.props.setActiveAlert(false); this.props.registerState.setState( { usernameInputText: '', }, () => { invariant(this.usernameInput, 'ref should exist'); this.usernameInput.focus(); }, ); }; async registerAction(extraInfo: LogInExtraInfo) { try { const result = await this.props.register({ username: this.props.registerState.state.usernameInputText, password: this.props.registerState.state.passwordInputText, ...extraInfo, }); this.props.setActiveAlert(false); await setNativeCredentials({ username: result.currentUserInfo.username, password: this.props.registerState.state.passwordInputText, }); return result; } catch (e) { - if (e.message === 'username_reserved') { - Alert.alert( - 'Username reserved', - 'This username is currently reserved. Please contact support@' + - 'comm.app if you would like to claim this account.', - [{ text: 'OK', onPress: this.onUsernameAlertAcknowledged }], - { cancelable: false }, - ); - } else if (e.message === 'username_taken') { + if (e.message === 'username_taken') { Alert.alert( 'Username taken', 'An account with that username already exists', [{ text: 'OK', onPress: this.onUsernameAlertAcknowledged }], { cancelable: false }, ); } else if (e.message === 'client_version_unsupported') { const app = Platform.select({ ios: 'App Store', android: 'Play Store', }); Alert.alert( 'App out of date', "Your app version is pretty old, and the server doesn't know how " + `to speak to it anymore. Please use the ${app} app to update!`, [{ text: 'OK', onPress: this.onAppOutOfDateAlertAcknowledged }], { cancelable: false }, ); } else { Alert.alert( 'Unknown error', 'Uhh... try again?', [{ text: 'OK', onPress: this.onUnknownErrorAlertAcknowledged }], { cancelable: false }, ); } throw e; } } onUnknownErrorAlertAcknowledged = () => { this.props.setActiveAlert(false); this.props.registerState.setState( { usernameInputText: '', passwordInputText: '', confirmPasswordInputText: '', }, () => { invariant(this.usernameInput, 'ref should exist'); this.usernameInput.focus(); }, ); }; onAppOutOfDateAlertAcknowledged = () => { this.props.setActiveAlert(false); }; } const styles = StyleSheet.create({ container: { zIndex: 2, }, footer: { alignItems: 'stretch', flexDirection: 'row', flexShrink: 1, justifyContent: 'space-between', paddingLeft: 24, }, hyperlinkText: { color: '#036AFF', fontWeight: 'bold', }, icon: { bottom: 10, left: 4, position: 'absolute', }, input: { paddingLeft: 35, }, notice: { alignSelf: 'center', display: 'flex', flexShrink: 1, maxWidth: 190, paddingBottom: 18, paddingRight: 8, paddingTop: 12, }, noticeText: { color: '#444', fontSize: 13, lineHeight: 20, textAlign: 'center', }, row: { marginHorizontal: 24, }, }); const loadingStatusSelector = createLoadingStatusSelector(registerActionTypes); const ConnectedRegisterPanel: React.ComponentType = React.memo( function ConnectedRegisterPanel(props: BaseProps) { const loadingStatus = useSelector(loadingStatusSelector); const navContext = React.useContext(NavContext); const logInExtraInfo = useSelector(state => nativeLogInExtraInfoSelector({ redux: state, navContext, }), ); const dispatchActionPromise = useDispatchActionPromise(); const callRegister = useServerCall(register); return ( ); }, ); export default ConnectedRegisterPanel; diff --git a/server/src/creators/account-creator.js b/server/src/creators/account-creator.js index 4328c15c0..6c0918e21 100644 --- a/server/src/creators/account-creator.js +++ b/server/src/creators/account-creator.js @@ -1,186 +1,181 @@ // @flow import invariant from 'invariant'; import bcrypt from 'twin-bcrypt'; import ashoat from 'lib/facts/ashoat'; import bots from 'lib/facts/bots'; import genesis from 'lib/facts/genesis'; import { validUsernameRegex, oldValidUsernameRegex, } from 'lib/shared/account-utils'; import { hasMinCodeVersion } from 'lib/shared/version-utils'; import type { RegisterResponse, RegisterRequest, } from 'lib/types/account-types'; import { messageTypes } from 'lib/types/message-types'; import { threadTypes } from 'lib/types/thread-types'; import { ServerError } from 'lib/utils/errors'; import { values } from 'lib/utils/objects'; -import { reservedUsernamesSet } from 'lib/utils/reserved-users'; import { dbQuery, SQL } from '../database/database'; import { deleteCookie } from '../deleters/cookie-deleters'; import { fetchThreadInfos } from '../fetchers/thread-fetchers'; import { fetchLoggedInUserInfo, fetchKnownUserInfos, } from '../fetchers/user-fetchers'; import { verifyCalendarQueryThreadIDs } from '../responders/entry-responders'; import { createNewUserCookie, setNewSession } from '../session/cookies'; import { createScriptViewer } from '../session/scripts'; import type { Viewer } from '../session/viewer'; import { updateThread } from '../updaters/thread-updaters'; import createIDs from './id-creator'; import createMessages from './message-creator'; import { createThread, createPrivateThread, privateThreadDescription, } from './thread-creator'; const { commbot } = bots; const ashoatMessages = [ 'welcome to Comm!', 'as you inevitably discover bugs, have feature requests, or design ' + 'suggestions, feel free to message them to me in the app.', ]; const privateMessages = [privateThreadDescription]; async function createAccount( viewer: Viewer, request: RegisterRequest, ): Promise { if (request.password.trim() === '') { throw new ServerError('empty_password'); } const usernameRegex = hasMinCodeVersion(viewer.platformDetails, 69) ? validUsernameRegex : oldValidUsernameRegex; if (request.username.search(usernameRegex) === -1) { throw new ServerError('invalid_username'); } const usernameQuery = SQL` SELECT COUNT(id) AS count FROM users WHERE LCASE(username) = LCASE(${request.username}) `; const promises = [dbQuery(usernameQuery)]; const { calendarQuery } = request; if (calendarQuery) { promises.push(verifyCalendarQueryThreadIDs(calendarQuery)); } const [[usernameResult]] = await Promise.all(promises); - if (reservedUsernamesSet.has(request.username.toLowerCase())) { - throw new ServerError('username_reserved'); - } - if (usernameResult[0].count !== 0) { throw new ServerError('username_taken'); } const hash = bcrypt.hashSync(request.password); const time = Date.now(); const deviceToken = request.deviceTokenUpdateRequest ? request.deviceTokenUpdateRequest.deviceToken : viewer.deviceToken; const [id] = await createIDs('users', 1); const newUserRow = [id, request.username, hash, time]; const newUserQuery = SQL` INSERT INTO users(id, username, hash, creation_time) VALUES ${[newUserRow]} `; const [userViewerData] = await Promise.all([ createNewUserCookie(id, { platformDetails: request.platformDetails, deviceToken, }), deleteCookie(viewer.cookieID), dbQuery(newUserQuery), ]); viewer.setNewCookie(userViewerData); if (calendarQuery) { await setNewSession(viewer, calendarQuery, 0); } await updateThread( createScriptViewer(ashoat.id), { threadID: genesis.id, changes: { newMemberIDs: [id] }, }, { forceAddMembers: true, silenceMessages: true, ignorePermissions: true }, ); const [privateThreadResult, ashoatThreadResult] = await Promise.all([ createPrivateThread(viewer, request.username), createThread( viewer, { type: threadTypes.PERSONAL, initialMemberIDs: [ashoat.id], }, { forceAddMembers: true }, ), ]); const ashoatThreadID = ashoatThreadResult.newThreadInfo ? ashoatThreadResult.newThreadInfo.id : ashoatThreadResult.newThreadID; const privateThreadID = privateThreadResult.newThreadInfo ? privateThreadResult.newThreadInfo.id : privateThreadResult.newThreadID; invariant( ashoatThreadID && privateThreadID, 'createThread should return either newThreadInfo or newThreadID', ); let messageTime = Date.now(); const ashoatMessageDatas = ashoatMessages.map(message => ({ type: messageTypes.TEXT, threadID: ashoatThreadID, creatorID: ashoat.id, time: messageTime++, text: message, })); const privateMessageDatas = privateMessages.map(message => ({ type: messageTypes.TEXT, threadID: privateThreadID, creatorID: commbot.userID, time: messageTime++, text: message, })); const messageDatas = [...ashoatMessageDatas, ...privateMessageDatas]; const [ messageInfos, threadsResult, userInfos, currentUserInfo, ] = await Promise.all([ createMessages(viewer, messageDatas), fetchThreadInfos(viewer), fetchKnownUserInfos(viewer), fetchLoggedInUserInfo(viewer), ]); const rawMessageInfos = [ ...ashoatThreadResult.newMessageInfos, ...privateThreadResult.newMessageInfos, ...messageInfos, ]; return { id, rawMessageInfos, currentUserInfo, cookieChange: { threadInfos: threadsResult.threadInfos, userInfos: values(userInfos), }, }; } export default createAccount;