@ -0,0 +1,25 @@
|
||||
name: Validate
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
name: Validate
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.3
|
||||
- uses: actions/setup-node@v2.1.2
|
||||
with:
|
||||
node-version: '14'
|
||||
- name: Restore npm cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
- name: Validate
|
||||
run: npm run validate
|
@ -0,0 +1,37 @@
|
||||
# Contributing
|
||||
|
||||
Wappalyzer is an [MIT-licensed](https://github.com/aliasio/wappalyzer/blob/master/LICENSE), open source project written in JavaScript. Anyone is welcome to contribute.
|
||||
|
||||
## Getting started
|
||||
|
||||
To get started, see the [README](https://github.com/aliasio/wappalyzer/blob/master/README.md).
|
||||
|
||||
## Submitting changes
|
||||
|
||||
- First, run `yarn run validate` to identify any issues.
|
||||
- Use descriptive commit messages, e.g. 'Add WordPress detection'.
|
||||
- Push your commits to a new branch on your own fork.
|
||||
- Finally, submit a [pull request](https://help.github.com/articles/about-pull-requests/) and describe your changes.
|
||||
|
||||
## Adding a new technology
|
||||
|
||||
Wappalyzer uses [regular expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) to fingerprint technologies. Refer to the [specification](https://github.com/AliasIO/wappalyzer/blob/master/README.md#specification) for detail.
|
||||
|
||||
- Add a new block to [`src/technologies.json`](https://github.com/aliasio/wappalyzer/blob/master/src/technologies.json).
|
||||
- Add an icon to [`src/drivers/webextension/images/icons`](https://github.com/aliasio/wappalyzer/tree/master/src/drivers/webextension/images/icons). The image must be square, either SVG or PNG (32 x 32 pixels).
|
||||
|
||||
Only widely used technologies are accepted. When creating a pull request, include ten or more links to websites that use the application, a GitHub page with at least 1,000 stars or anything that will help establish the size of the user base.
|
||||
|
||||
## Adding a new category
|
||||
|
||||
Please [open an issue on GitHub](https://github.com/aliasio/wappalyzer/issues) first to discuss the need for a new category.
|
||||
|
||||
To add a category, edit [`src/technologies.json`](https://github.com/aliasio/wappalyzer/blob/master/src/technologies.json) and update every [locale](https://github.com/aliasio/wappalyzer/tree/master/src/drivers/webextension/_locales). You may use the English category name in all of them.
|
||||
|
||||
## Adding a new translation
|
||||
|
||||
To add a new translation, copy the `en` folder in [`src/drivers/webextension/_locales`](https://github.com/aliasio/wappalyzer/tree/master/src/drivers/webextension/_locales), rename it to the relevant two-letter country code and update the containing `messages.json` file.
|
||||
|
||||
## Adding a new feature
|
||||
|
||||
Please [open an issue on GitHub](https://github.com/aliasio/wappalyzer/issues) first. New features and large changes are rarely accepted without prior discussion.
|
@ -0,0 +1,137 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const { convertFile } = require('convert-svg-to-png')
|
||||
|
||||
const appPaths = () => {
|
||||
const fileDir = path.dirname(require.main.filename).split('/')
|
||||
// Remove current bin directory
|
||||
fileDir.pop()
|
||||
const appDir = fileDir.join('/')
|
||||
|
||||
return {
|
||||
basePath: fileDir,
|
||||
appPath: appDir,
|
||||
iconPath: appDir + '/src/drivers/webextension/images/icons',
|
||||
convertPath: appDir + '/src/drivers/webextension/images/icons/converted',
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy files from source to destination.
|
||||
* @param source
|
||||
* @param destination
|
||||
*/
|
||||
function copyFiles(source, destination) {
|
||||
// File destination will be created or overwritten by default.
|
||||
fs.copyFileSync(source, destination)
|
||||
// console.log(`${source} -> ${destination}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get extension of image file.
|
||||
* @returns {string}
|
||||
*/
|
||||
function getFileExtension(filePath) {
|
||||
return path.extname(filePath)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get base name of image file.
|
||||
* @returns {string}
|
||||
*/
|
||||
function getFileName(filePath) {
|
||||
return path.basename(filePath, getFileExtension(filePath))
|
||||
}
|
||||
|
||||
function getConvertFileName(filePath) {
|
||||
const name = getFileName(filePath)
|
||||
return `${appPaths().convertPath}/${name}.png`
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if converted image exists
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function checkFileExists(imagePath) {
|
||||
const fileExists = fs.existsSync(imagePath)
|
||||
return fileExists
|
||||
}
|
||||
|
||||
function checkIfFile(filePath) {
|
||||
return fs.statSync(filePath).isFile()
|
||||
}
|
||||
|
||||
function diffFiles(fileOne, fileTwo) {
|
||||
const f1 = fs.readFileSync(fileOne)
|
||||
const f2 = fs.readFileSync(fileTwo)
|
||||
return f1.equals(f2)
|
||||
}
|
||||
|
||||
function dateModified(file) {
|
||||
return fs.statSync(file).mtime
|
||||
}
|
||||
|
||||
function dateDiff(file) {
|
||||
const now = new Date().getTime()
|
||||
const then = dateModified(file).getTime()
|
||||
return Math.round(Math.abs((then - now) / 86400000))
|
||||
}
|
||||
|
||||
// Main script
|
||||
fs.readdirSync(appPaths().iconPath).forEach((fileName) => {
|
||||
const image = {
|
||||
id: fileName,
|
||||
path: `${appPaths().iconPath}/${fileName}`,
|
||||
convertPath: `${appPaths().convertPath}/${fileName}`,
|
||||
async convertAndCopy() {
|
||||
await convertFile(this.path, {
|
||||
height: 32,
|
||||
width: 32,
|
||||
outputFilePath: this.convertPath,
|
||||
}).then((outputFile) => {
|
||||
console.log(`SVG Converted: ${outputFile}`)
|
||||
})
|
||||
},
|
||||
processFile() {
|
||||
// Setup variables.
|
||||
const ext = getFileExtension(this.path)
|
||||
|
||||
// If SVG, run checks.
|
||||
if (ext === '.svg') {
|
||||
// Check if converted file exists.
|
||||
const convertFilePath = getConvertFileName(this.path)
|
||||
if (checkFileExists(convertFilePath)) {
|
||||
// If file has changed in past 7 days.
|
||||
if (dateDiff(this.path) > 8) {
|
||||
console.log(`File exists, skipping: ${this.id}`)
|
||||
return null
|
||||
}
|
||||
}
|
||||
// Convert and copy file.
|
||||
this.convertAndCopy()
|
||||
} else {
|
||||
// If PNG or other, just copy the file as-is.
|
||||
// eslint-disable-next-line no-lonely-if
|
||||
if (checkIfFile(this.path)) {
|
||||
copyFiles(this.path, this.convertPath)
|
||||
} else {
|
||||
console.info('Not a file, skipping...')
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
image.processFile()
|
||||
})
|
||||
|
||||
/**
|
||||
|
||||
cd ; cp *.svg converted ; cd converted ; convert-svg-to-png *.svg --width 32 --height 32 ; rm *.svg
|
||||
(async() => {
|
||||
const inputFilePath = '/path/to/my-image.svg';
|
||||
const outputFilePath = await convertFile(inputFilePath);
|
||||
|
||||
console.log(outputFilePath);
|
||||
//=> "/path/to/my-image.png"
|
||||
})();
|
||||
*/
|
@ -1,92 +1,99 @@
|
||||
{
|
||||
"github": { "message": "Forke Wappalyzer bei GitHub!" },
|
||||
"twitter": { "message": "Folge Wappalyzer bei Twitter" },
|
||||
"website": { "message": "Gehe zu wappalyzer.com" },
|
||||
"options": { "message": "Optionen" },
|
||||
"optionsSave": { "message": "Optionen speichern" },
|
||||
"optionsSaved": { "message": "Gespeichert" },
|
||||
"optionUpgradeMessage": { "message": "Benachrichtige mich bei Upgrades" },
|
||||
"optionDynamicIcon": { "message": "Applikations Icon anstatt des Wappalyzer Icons verwenden" },
|
||||
"optionTracking": { "message": "Anonyme Statistiken an wappalyzer.com übermitteln" },
|
||||
"optionThemeMode": { "message": "Aktivieren dunklen Modus Kompatibilität." },
|
||||
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
|
||||
"disableOnDomain": { "message": "Disable on this website" },
|
||||
"clearCache": { "message": "Clear cached detections" },
|
||||
"nothingToDo": { "message": "Nichts zu tun." },
|
||||
"noAppsDetected": { "message": "Keine Applikation entdeckt." },
|
||||
"categoryPin": { "message": "Immer Icon anzeigen" },
|
||||
"termsAccept": { "message": "Accept" },
|
||||
"termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. This can be disabled in the settings." },
|
||||
"privacyPolicy": { "message": "Privacy policy" },
|
||||
"createAlert": { "message": "Create an alert for this website" },
|
||||
"categoryName1": { "message": "CMS" },
|
||||
"categoryName2": { "message": "Nachrichten Board" },
|
||||
"categoryName3": { "message": "Datenbankverwaltung" },
|
||||
"categoryName4": { "message": "Dokumentations Tool" },
|
||||
"categoryName5": { "message": "Widget" },
|
||||
"categoryName6": { "message": "Ecommerce" },
|
||||
"categoryName7": { "message": "Fotogalerien" },
|
||||
"categoryName8": { "message": "Wikis" },
|
||||
"categoryName9": { "message": "Hosting-Panels" },
|
||||
"categoryName10": { "message": "Statistiken" },
|
||||
"categoryName11": { "message": "Blog" },
|
||||
"categoryName12": { "message": "JavaScript Framework" },
|
||||
"categoryName13": { "message": "Fehlertracker" },
|
||||
"categoryName14": { "message": "Videospieler" },
|
||||
"categoryName15": { "message": "Kommentarsystem" },
|
||||
"categoryName16": { "message": "Security" },
|
||||
"categoryName17": { "message": "Schrift Script" },
|
||||
"categoryName18": { "message": "Web Framework" },
|
||||
"categoryName19": { "message": "Sonstiges" },
|
||||
"categoryName20": { "message": "Editor" },
|
||||
"categoryName21": { "message": "LMS" },
|
||||
"categoryName22": { "message": "Web Server" },
|
||||
"categoryName23": { "message": "Cache Tool" },
|
||||
"categoryName24": { "message": "Rich Text Editor" },
|
||||
"categoryName25": { "message": "JavaScript Graphics" },
|
||||
"categoryName26": { "message": "Mobile Framework" },
|
||||
"categoryName27": { "message": "Programmiersprache" },
|
||||
"categoryName28": { "message": "Betriebssystem" },
|
||||
"categoryName29": { "message": "Suchmaschine" },
|
||||
"categoryName30": { "message": "Webmail" },
|
||||
"categoryName31": { "message": "CDN" },
|
||||
"categoryName32": { "message": "Marketing Automation" },
|
||||
"categoryName33": { "message": "Web Server Erweiterung" },
|
||||
"categoryName34": { "message": "Datenbank" },
|
||||
"categoryName35": { "message": "Map" },
|
||||
"categoryName36": { "message": "Werbenetzwerk" },
|
||||
"categoryName37": { "message": "Netzwerkdienst" },
|
||||
"categoryName38": { "message": "Medienserver" },
|
||||
"categoryName39": { "message": "Webcam" },
|
||||
"categoryName40": { "message": "Drucker" },
|
||||
"categoryName41": { "message": "Zahlungsverarbeiter" },
|
||||
"categoryName42": { "message": "Schlagwort Manager" },
|
||||
"categoryName43": { "message": "Bezahlblockade" },
|
||||
"categoryName44": { "message": "Build/CI-System" },
|
||||
"categoryName45": { "message": "SCADA System" },
|
||||
"categoryName46": { "message": "Fernzugriff" },
|
||||
"categoryName47": { "message": "Entwicklungswerkzeug" },
|
||||
"categoryName48": { "message": "Netzwerkspeicher" },
|
||||
"categoryName49": { "message": "Feedleser" },
|
||||
"categoryName50": { "message": "Dokumentmanagementsysteme" },
|
||||
"categoryName51": { "message": "Startseitenersteller" },
|
||||
"categoryName52": { "message": "Live-Chat" },
|
||||
"categoryName53": { "message": "CRM" },
|
||||
"github": { "message": "Forke Wappalyzer bei GitHub!" },
|
||||
"twitter": { "message": "Folge Wappalyzer bei Twitter" },
|
||||
"website": { "message": "Gehe zu wappalyzer.com" },
|
||||
"options": { "message": "Optionen" },
|
||||
"optionsSave": { "message": "Optionen speichern" },
|
||||
"optionsSaved": { "message": "Gespeichert" },
|
||||
"optionUpgradeMessage": { "message": "Benachrichtige mich bei Upgrades" },
|
||||
"optionDynamicIcon": { "message": "Applikations Icon anstatt des Wappalyzer Icons verwenden" },
|
||||
"optionTracking": { "message": "Anonyme Statistiken an wappalyzer.com übermitteln" },
|
||||
"optionThemeMode": { "message": "Dunkel-Modus aktivieren" },
|
||||
"optionBadge": { "message": "Anzahl der identifizierten Optionen am Icon anzeigen" },
|
||||
"disableOnDomain": { "message": "Auf dieser Website deaktivieren" },
|
||||
"clearCache": { "message": "Cache leeren" },
|
||||
"nothingToDo": { "message": "Nichts zu tun." },
|
||||
"noAppsDetected": { "message": "Keine Applikationen gefunden" },
|
||||
"categoryPin": { "message": "Icon immer anzeigen" },
|
||||
"termsAccept": { "message": "I'm ok with that" },
|
||||
"termsDecline": { "message": "Disable" },
|
||||
"termsContent": { "message": "Diese Erweiterung sendet anonyme Informationen über Websites, die Sie besuchen, einschließlich der Domain und der identifizierten Technologien, an <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. Dies kann in den Einstellungen deaktiviert werden." },
|
||||
"privacyPolicy": { "message": "Datenschutzerklärung" },
|
||||
"createAlert": { "message": "Alarm für diese Website erstellen" },
|
||||
"leadLists": { "message": "Lead generation tools" },
|
||||
"categoryName1": { "message": "CMS" },
|
||||
"categoryName2": { "message": "Nachrichten Board" },
|
||||
"categoryName3": { "message": "Datenbankverwaltung" },
|
||||
"categoryName4": { "message": "Dokumentations Tool" },
|
||||
"categoryName5": { "message": "Widget" },
|
||||
"categoryName6": { "message": "E-Commerce" },
|
||||
"categoryName7": { "message": "Fotogalerien" },
|
||||
"categoryName8": { "message": "Wikis" },
|
||||
"categoryName9": { "message": "Hosting-Panels" },
|
||||
"categoryName10": { "message": "Statistiken" },
|
||||
"categoryName11": { "message": "Blog" },
|
||||
"categoryName12": { "message": "JavaScript Frameworks" },
|
||||
"categoryName13": { "message": "Ticketsysteme" },
|
||||
"categoryName14": { "message": "Videoplayer" },
|
||||
"categoryName15": { "message": "Kommentarsystem" },
|
||||
"categoryName16": { "message": "Security" },
|
||||
"categoryName17": { "message": "Schrift Script" },
|
||||
"categoryName18": { "message": "Web Frameworks" },
|
||||
"categoryName19": { "message": "Sonstiges" },
|
||||
"categoryName20": { "message": "Editor" },
|
||||
"categoryName21": { "message": "LMS" },
|
||||
"categoryName22": { "message": "Web Server" },
|
||||
"categoryName23": { "message": "Cache Tool" },
|
||||
"categoryName24": { "message": "Rich Text Editor" },
|
||||
"categoryName25": { "message": "JavaScript Graphics" },
|
||||
"categoryName26": { "message": "Mobile Framework" },
|
||||
"categoryName27": { "message": "Programmiersprache" },
|
||||
"categoryName28": { "message": "Betriebssysteme" },
|
||||
"categoryName29": { "message": "Suchmaschinen" },
|
||||
"categoryName30": { "message": "Webmail" },
|
||||
"categoryName31": { "message": "CDN" },
|
||||
"categoryName32": { "message": "Marketing Automation" },
|
||||
"categoryName33": { "message": "Web Server Erweiterungen" },
|
||||
"categoryName34": { "message": "Datenbanken" },
|
||||
"categoryName35": { "message": "Karten" },
|
||||
"categoryName36": { "message": "Werbenetzwerke" },
|
||||
"categoryName37": { "message": "Netzwerkdienste" },
|
||||
"categoryName38": { "message": "Medienserver" },
|
||||
"categoryName39": { "message": "Web-Kameras" },
|
||||
"categoryName40": { "message": "Drucker" },
|
||||
"categoryName41": { "message": "Zahlungsverarbeiter" },
|
||||
"categoryName42": { "message": "Tag Manager" },
|
||||
"categoryName43": { "message": "Bezahlblockade" },
|
||||
"categoryName44": { "message": "CI-Systeme" },
|
||||
"categoryName45": { "message": "SCADA System" },
|
||||
"categoryName46": { "message": "Fernzugriff" },
|
||||
"categoryName47": { "message": "Entwicklungswerkzeuge" },
|
||||
"categoryName48": { "message": "Netzwerkspeicher" },
|
||||
"categoryName49": { "message": "Feedleser" },
|
||||
"categoryName50": { "message": "Dokumentmanagementsysteme" },
|
||||
"categoryName51": { "message": "Website Baukästen" },
|
||||
"categoryName52": { "message": "Live-Chat" },
|
||||
"categoryName53": { "message": "CRM" },
|
||||
"categoryName54": { "message": "SEO" },
|
||||
"categoryName55": { "message": "Buchhaltung" },
|
||||
"categoryName56": { "message": "Cryptominer" },
|
||||
"categoryName57": { "message": "Statischer Seitengenerator" },
|
||||
"categoryName58": { "message": "Benutzer-Einbindung" },
|
||||
"categoryName59": { "message": "JavaScript Bibliotheken" },
|
||||
"categoryName60": { "message": "Containers" },
|
||||
"categoryName61": { "message": "SaaS" },
|
||||
"categoryName62": { "message": "PaaS" },
|
||||
"categoryName63": { "message": "IaaS" },
|
||||
"categoryName64": { "message": "Reverse Proxy" },
|
||||
"categoryName65": { "message": "Load Balancer" },
|
||||
"categoryName66": { "message": "UI Frameworks" },
|
||||
"categoryName67": { "message": "Cookie compliance" },
|
||||
"categoryName68": { "message": "Accessibility"},
|
||||
"categoryName69": { "message": "Social login"},
|
||||
"categoryName70": { "message": "SSL/TLS certificate authority"}
|
||||
"categoryName55": { "message": "Buchhaltung" },
|
||||
"categoryName56": { "message": "Cryptominer" },
|
||||
"categoryName57": { "message": "Statischer Seitengenerator" },
|
||||
"categoryName58": { "message": "Benutzer-Onboarding" },
|
||||
"categoryName59": { "message": "JavaScript Bibliotheken" },
|
||||
"categoryName60": { "message": "Container" },
|
||||
"categoryName61": { "message": "SaaS" },
|
||||
"categoryName62": { "message": "PaaS" },
|
||||
"categoryName63": { "message": "IaaS" },
|
||||
"categoryName64": { "message": "Reverse Proxies" },
|
||||
"categoryName65": { "message": "Load Balancer" },
|
||||
"categoryName66": { "message": "UI Frameworks" },
|
||||
"categoryName67": { "message": "Cookie compliance" },
|
||||
"categoryName68": { "message": "Barrierefreiheit" },
|
||||
"categoryName69": { "message": "Social Login" },
|
||||
"categoryName70": { "message": "SSL/TLS certificate authority" },
|
||||
"categoryName71": { "message": "Partnerprogram" },
|
||||
"categoryName72": { "message": "Appointment scheduling" },
|
||||
"categoryName73": { "message": "Surveys" },
|
||||
"categoryName74": { "message": "A/B testing" },
|
||||
"categoryName75": { "message": "Email" }
|
||||
}
|
||||
|
After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 643 B After Width: | Height: | Size: 540 B |
After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 858 B |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 838 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 284 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 502 B |
After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 8.0 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 720 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 862 B |
After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 371 B |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 247 B |
After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 755 B |
After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 603 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 196 KiB |
After Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 389 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 814 B |
After Width: | Height: | Size: 270 B |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 655 B |
Before Width: | Height: | Size: 361 B |
After Width: | Height: | Size: 2.9 KiB |