whopper 0.5.9 → 0.6.0
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.
- package/dist/browser/index.d.ts.map +1 -1
- package/dist/browser/index.js +56 -3
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.test.js +133 -0
- package/dist/browser/index.test.js.map +1 -1
- package/dist/browser/types.d.ts +1 -0
- package/dist/browser/types.d.ts.map +1 -1
- package/dist/commands/detect.d.ts.map +1 -1
- package/dist/commands/detect.js +2 -0
- package/dist/commands/detect.js.map +1 -1
- package/dist/commands/detect.test.js +5 -0
- package/dist/commands/detect.test.js.map +1 -1
- package/dist/commands/detect_utils.d.ts.map +1 -1
- package/dist/commands/detect_utils.js +23 -5
- package/dist/commands/detect_utils.js.map +1 -1
- package/dist/commands/detect_utils.test.js +86 -9
- package/dist/commands/detect_utils.test.js.map +1 -1
- package/dist/signatures/_types.d.ts +1 -0
- package/dist/signatures/_types.d.ts.map +1 -1
- package/dist/signatures/index.d.ts.map +1 -1
- package/dist/signatures/index.js +2 -0
- package/dist/signatures/index.js.map +1 -1
- package/dist/signatures/signatures.test.js +16 -0
- package/dist/signatures/signatures.test.js.map +1 -1
- package/dist/signatures/technologies/drupal.d.ts.map +1 -1
- package/dist/signatures/technologies/drupal.js +17 -0
- package/dist/signatures/technologies/drupal.js.map +1 -1
- package/dist/signatures/technologies/drupal.test.d.ts +2 -0
- package/dist/signatures/technologies/drupal.test.d.ts.map +1 -0
- package/dist/signatures/technologies/drupal.test.js +76 -0
- package/dist/signatures/technologies/drupal.test.js.map +1 -0
- package/dist/signatures/technologies/power_cms.d.ts +3 -0
- package/dist/signatures/technologies/power_cms.d.ts.map +1 -0
- package/dist/signatures/technologies/power_cms.js +51 -0
- package/dist/signatures/technologies/power_cms.js.map +1 -0
- package/dist/signatures/technologies/power_cms.test.d.ts +2 -0
- package/dist/signatures/technologies/power_cms.test.d.ts.map +1 -0
- package/dist/signatures/technologies/power_cms.test.js +83 -0
- package/dist/signatures/technologies/power_cms.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { movableTypeSignature } from "./movable_type.js";
|
|
2
|
+
import { perlSignature } from "./perl.js";
|
|
3
|
+
// PowerCMS is an Alfasado CMS built on top of Movable Type, so it shares the
|
|
4
|
+
// mt.cgi admin script and mt-static asset path with MT. Detection keys off the
|
|
5
|
+
// PowerCMS-specific plugin static path to tell it apart from plain MT, and the
|
|
6
|
+
// active mt.cgi admin probe captures the version from the admin footer when
|
|
7
|
+
// available (best-effort; admin pages are not always reachable).
|
|
8
|
+
const adminPageRegexes = [
|
|
9
|
+
// Admin footer version text, e.g. "PowerCMS version 5.43" / "PowerCMS 4.46".
|
|
10
|
+
// Version-bearing patterns come first so the version is captured when present.
|
|
11
|
+
// PowerCMS version numbers have irregular precision (2.0493 / 4.46 / 5.43),
|
|
12
|
+
// so accept an arbitrary number of dot-separated groups.
|
|
13
|
+
"PowerCMS version ([0-9]+(?:\\.[0-9]+)*)", // v5 footer
|
|
14
|
+
"PowerCMS ([0-9]+(?:\\.[0-9]+)*)", // v4 footer
|
|
15
|
+
// v6/v7 dropped the product-name prefix and show just "version 6.83". This
|
|
16
|
+
// bare fallback is intentionally last so v4/v5 still match the prefixed forms
|
|
17
|
+
// above (first-hit-wins), limiting its blast radius to v6/v7 pages. Requiring
|
|
18
|
+
// at least one dot avoids picking up single-token "version 3" style noise, and
|
|
19
|
+
// the leading \b prevents matching words that merely end in "version"
|
|
20
|
+
// (e.g. "Subversion 1.14.2").
|
|
21
|
+
"\\bversion ([0-9]+\\.[0-9]+(?:\\.[0-9]+)*)", // v6/v7 footer
|
|
22
|
+
"/mt-static/plugins/PowerCMS/", // PowerCMS-specific marker, confirms even without a version
|
|
23
|
+
];
|
|
24
|
+
const activeRules = [
|
|
25
|
+
"/mt.cgi?__mode=logout", // root install (common)
|
|
26
|
+
"/mt/mt.cgi?__mode=logout",
|
|
27
|
+
"/cgi-bin/mt/mt.cgi?__mode=logout",
|
|
28
|
+
"/blog/mt.cgi?__mode=logout",
|
|
29
|
+
].map((path) => ({ path, bodyRegexes: adminPageRegexes }));
|
|
30
|
+
// Detects PowerCMS from the PowerCMS-specific plugin static path on public
|
|
31
|
+
// pages, then confirms/extracts the version via the mt.cgi admin probe. When
|
|
32
|
+
// PowerCMS is detected, Movable Type is excluded from the output to avoid the
|
|
33
|
+
// underlying MT being reported alongside the actual product.
|
|
34
|
+
export const powerCmsSignature = {
|
|
35
|
+
name: "PowerCMS",
|
|
36
|
+
description: "PowerCMS is a Movable Type-based content management system by Alfasado Inc.",
|
|
37
|
+
cpe: "cpe:/a:alfasado:powercms", // CPE 2.2
|
|
38
|
+
rule: {
|
|
39
|
+
confidence: "high",
|
|
40
|
+
urls: [
|
|
41
|
+
"/mt-static/plugins/PowerCMS/", // distinguishes PowerCMS from plain Movable Type
|
|
42
|
+
],
|
|
43
|
+
bodies: [
|
|
44
|
+
"/mt-static/plugins/PowerCMS/", // same path referenced inline in public HTML
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
activeRules,
|
|
48
|
+
excludes: [movableTypeSignature.name], // PowerCMS supersedes the underlying Movable Type
|
|
49
|
+
impliedSoftwares: [perlSignature.name], // PowerCMS is a Perl application (like MT)
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=power_cms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"power_cms.js","sourceRoot":"","sources":["../../../src/signatures/technologies/power_cms.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,6EAA6E;AAC7E,+EAA+E;AAC/E,+EAA+E;AAC/E,4EAA4E;AAC5E,iEAAiE;AACjE,MAAM,gBAAgB,GAAG;IACvB,6EAA6E;IAC7E,+EAA+E;IAC/E,4EAA4E;IAC5E,yDAAyD;IACzD,yCAAyC,EAAE,YAAY;IACvD,iCAAiC,EAAE,YAAY;IAC/C,2EAA2E;IAC3E,8EAA8E;IAC9E,8EAA8E;IAC9E,+EAA+E;IAC/E,sEAAsE;IACtE,8BAA8B;IAC9B,4CAA4C,EAAE,eAAe;IAC7D,8BAA8B,EAAE,4DAA4D;CAC7F,CAAC;AAEF,MAAM,WAAW,GAAiB;IAChC,uBAAuB,EAAE,wBAAwB;IACjD,0BAA0B;IAC1B,kCAAkC;IAClC,4BAA4B;CAC7B,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC;AAE3D,2EAA2E;AAC3E,6EAA6E;AAC7E,8EAA8E;AAC9E,6DAA6D;AAC7D,MAAM,CAAC,MAAM,iBAAiB,GAAc;IAC1C,IAAI,EAAE,UAAU;IAChB,WAAW,EACT,6EAA6E;IAC/E,GAAG,EAAE,0BAA0B,EAAE,UAAU;IAC3C,IAAI,EAAE;QACJ,UAAU,EAAE,MAAM;QAClB,IAAI,EAAE;YACJ,8BAA8B,EAAE,iDAAiD;SAClF;QACD,MAAM,EAAE;YACN,8BAA8B,EAAE,6CAA6C;SAC9E;KACF;IACD,WAAW;IACX,QAAQ,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,kDAAkD;IACzF,gBAAgB,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,2CAA2C;CACpF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"power_cms.test.d.ts","sourceRoot":"","sources":["../../../src/signatures/technologies/power_cms.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { matchString } from "../../analyzer/match.js";
|
|
3
|
+
import { powerCmsSignature } from "./power_cms.js";
|
|
4
|
+
import { movableTypeSignature } from "./movable_type.js";
|
|
5
|
+
describe("powerCmsSignature", () => {
|
|
6
|
+
describe("rule (passive, public-facing marker)", () => {
|
|
7
|
+
const urls = powerCmsSignature.rule?.urls ?? [];
|
|
8
|
+
const bodies = powerCmsSignature.rule?.bodies ?? [];
|
|
9
|
+
it("matches the PowerCMS plugin static path in URLs", () => {
|
|
10
|
+
const url = "https://example.com/mt-static/plugins/PowerCMS/css/style.css";
|
|
11
|
+
expect(urls.some((r) => matchString(url, r).hit)).toBe(true);
|
|
12
|
+
});
|
|
13
|
+
it("matches the PowerCMS plugin static path inline in HTML", () => {
|
|
14
|
+
const html = '<link rel="stylesheet" href="/mt-static/plugins/PowerCMS/x.css">';
|
|
15
|
+
expect(bodies.some((r) => matchString(html, r).hit)).toBe(true);
|
|
16
|
+
});
|
|
17
|
+
it("does not match a plain Movable Type asset path", () => {
|
|
18
|
+
const url = "https://example.com/mt-static/themes-base/blog.css";
|
|
19
|
+
expect(urls.some((r) => matchString(url, r).hit)).toBe(false);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
describe("activeRules (mt.cgi admin probe)", () => {
|
|
23
|
+
const rules = powerCmsSignature.activeRules ?? [];
|
|
24
|
+
it("probes the root and common install dirs with logout mode", () => {
|
|
25
|
+
expect(rules.map((r) => r.path)).toEqual([
|
|
26
|
+
"/mt.cgi?__mode=logout",
|
|
27
|
+
"/mt/mt.cgi?__mode=logout",
|
|
28
|
+
"/cgi-bin/mt/mt.cgi?__mode=logout",
|
|
29
|
+
"/blog/mt.cgi?__mode=logout",
|
|
30
|
+
]);
|
|
31
|
+
});
|
|
32
|
+
it("extracts the version from the 'PowerCMS version X.Y' footer", () => {
|
|
33
|
+
const regex = rules[0].bodyRegexes.find((r) => r.includes("PowerCMS version"));
|
|
34
|
+
const result = matchString("<p>PowerCMS version 5.43</p>", regex);
|
|
35
|
+
expect(result.hit).toBe(true);
|
|
36
|
+
expect(result.version).toBe("5.43");
|
|
37
|
+
});
|
|
38
|
+
it("extracts the version from the 'PowerCMS X.Y' footer", () => {
|
|
39
|
+
const result = rules[0].bodyRegexes
|
|
40
|
+
.map((r) => matchString("Powered by PowerCMS 4.46", r))
|
|
41
|
+
.find((r) => r.hit);
|
|
42
|
+
expect(result.hit).toBe(true);
|
|
43
|
+
expect(result.version).toBe("4.46");
|
|
44
|
+
});
|
|
45
|
+
it("extracts the version from the v6/v7 'version X.Y' footer (no product prefix)", () => {
|
|
46
|
+
const result = rules[0].bodyRegexes
|
|
47
|
+
.map((r) => matchString("<p>version 6.83</p>", r))
|
|
48
|
+
.find((r) => r.hit);
|
|
49
|
+
expect(result.hit).toBe(true);
|
|
50
|
+
expect(result.version).toBe("6.83");
|
|
51
|
+
});
|
|
52
|
+
it("does not pick up a single-token 'version 3' as a version", () => {
|
|
53
|
+
const bare = rules[0].bodyRegexes.find((r) => r === "\\bversion ([0-9]+\\.[0-9]+(?:\\.[0-9]+)*)");
|
|
54
|
+
expect(matchString("requires version 3", bare).hit).toBe(false);
|
|
55
|
+
});
|
|
56
|
+
it("does not match a word that merely ends in 'version' (e.g. Subversion)", () => {
|
|
57
|
+
const bare = rules[0].bodyRegexes.find((r) => r === "\\bversion ([0-9]+\\.[0-9]+(?:\\.[0-9]+)*)");
|
|
58
|
+
expect(matchString("Subversion 1.14.2", bare).hit).toBe(false);
|
|
59
|
+
});
|
|
60
|
+
it("extracts irregular-precision versions (e.g. 2.0493)", () => {
|
|
61
|
+
const result = rules[0].bodyRegexes
|
|
62
|
+
.map((r) => matchString("PowerCMS 2.0493", r))
|
|
63
|
+
.find((r) => r.hit);
|
|
64
|
+
expect(result.version).toBe("2.0493");
|
|
65
|
+
});
|
|
66
|
+
it("confirms PowerCMS via the plugin path even without a version", () => {
|
|
67
|
+
const regex = rules[0].bodyRegexes.find((r) => r.includes("/mt-static/plugins/PowerCMS/"));
|
|
68
|
+
const result = matchString('<img src="/mt-static/plugins/PowerCMS/logo.png">', regex);
|
|
69
|
+
expect(result.hit).toBe(true);
|
|
70
|
+
expect(result.version).toBeUndefined();
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
it("uses the Alfasado PowerCMS CPE 2.2 identifier", () => {
|
|
74
|
+
expect(powerCmsSignature.cpe).toBe("cpe:/a:alfasado:powercms");
|
|
75
|
+
});
|
|
76
|
+
it("excludes Movable Type so only PowerCMS is reported", () => {
|
|
77
|
+
expect(powerCmsSignature.excludes).toContain(movableTypeSignature.name);
|
|
78
|
+
});
|
|
79
|
+
it("implies Perl as the underlying runtime", () => {
|
|
80
|
+
expect(powerCmsSignature.impliedSoftwares).toContain("Perl");
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
//# sourceMappingURL=power_cms.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"power_cms.test.js","sourceRoot":"","sources":["../../../src/signatures/technologies/power_cms.test.ts"],"names":[],"mappings":"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"}
|