@huloglobal/vendure-plugin-geo-block 0.1.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/CHANGELOG.md +20 -0
- package/LICENSE +34 -0
- package/README.md +146 -0
- package/dist/geo-block.controller.d.ts +56 -0
- package/dist/geo-block.controller.d.ts.map +1 -0
- package/dist/geo-block.controller.js +236 -0
- package/dist/geo-block.controller.js.map +1 -0
- package/dist/geo-regions.d.ts +35 -0
- package/dist/geo-regions.d.ts.map +1 -0
- package/dist/geo-regions.js +62 -0
- package/dist/geo-regions.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.d.ts +47 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +140 -0
- package/dist/plugin.js.map +1 -0
- package/dist/proxy-headers.d.ts +37 -0
- package/dist/proxy-headers.d.ts.map +1 -0
- package/dist/proxy-headers.js +81 -0
- package/dist/proxy-headers.js.map +1 -0
- package/package.json +41 -0
- package/ui/components/geo-block.component.ts +573 -0
- package/ui/geo-block.module.ts +17 -0
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Type } from '@vendure/core';
|
|
2
|
+
export interface GeoBlockPluginOptions {
|
|
3
|
+
/** Public-facing host of the Vendure server. Used in licence
|
|
4
|
+
* domain matching — must match one of the JWT's `allowedDomains`. */
|
|
5
|
+
publicBaseUrl: string;
|
|
6
|
+
/** JWT licence key. Without it, the public site-config endpoint
|
|
7
|
+
* still resolves the rules but always returns `enabled: false`. */
|
|
8
|
+
licenceKey?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function getOptions(): GeoBlockPluginOptions;
|
|
11
|
+
/**
|
|
12
|
+
* `@huloglobal/vendure-plugin-geo-block`
|
|
13
|
+
*
|
|
14
|
+
* Per-channel geo-restriction for Vendure storefronts. The plugin owns
|
|
15
|
+
* a flat `/geo-block/site-config` endpoint the storefront polls (cached
|
|
16
|
+
* client-side) plus an admin page for configuring region presets,
|
|
17
|
+
* extra allowed countries, denylist, and UK-region subfilter.
|
|
18
|
+
*
|
|
19
|
+
* Add to your Vendure config:
|
|
20
|
+
*
|
|
21
|
+
* ```ts
|
|
22
|
+
* import { GeoBlockPlugin } from '@huloglobal/vendure-plugin-geo-block';
|
|
23
|
+
*
|
|
24
|
+
* export const config: VendureConfig = {
|
|
25
|
+
* plugins: [
|
|
26
|
+
* GeoBlockPlugin.init({
|
|
27
|
+
* publicBaseUrl: 'https://shop.example.com',
|
|
28
|
+
* licenceKey: process.env.HULO_LICENCE_KEY,
|
|
29
|
+
* }),
|
|
30
|
+
* ],
|
|
31
|
+
* };
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare class GeoBlockPlugin {
|
|
35
|
+
private static revocation;
|
|
36
|
+
static init(options: GeoBlockPluginOptions): Type<GeoBlockPlugin>;
|
|
37
|
+
static uiExtensions: {
|
|
38
|
+
extensionPath: string;
|
|
39
|
+
ngModules: {
|
|
40
|
+
type: "lazy";
|
|
41
|
+
route: string;
|
|
42
|
+
ngModuleFileName: string;
|
|
43
|
+
ngModuleName: string;
|
|
44
|
+
}[];
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,IAAI,EAAiB,MAAM,eAAe,CAAC;AAItF,MAAM,WAAW,qBAAqB;IAClC;0EACsE;IACtE,aAAa,EAAE,MAAM,CAAC;IACtB;wEACoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAiBD,wBAAgB,UAAU,IAAI,qBAAqB,CAA0B;AAE7E;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAiDa,cAAc;IACvB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAkC;IAE3D,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAAC,cAAc,CAAC;IA6BjE,MAAM,CAAC,YAAY;;;;;;;;MAUjB;CACL"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var GeoBlockPlugin_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.GeoBlockPlugin = void 0;
|
|
11
|
+
exports.getOptions = getOptions;
|
|
12
|
+
const core_1 = require("@vendure/core");
|
|
13
|
+
const vendure_licence_sdk_1 = require("@huloglobal/vendure-licence-sdk");
|
|
14
|
+
const geo_block_controller_1 = require("./geo-block.controller");
|
|
15
|
+
const HULO_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
|
|
16
|
+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoLmNM5UljRqe71drM6lR
|
|
17
|
+
Ba5vXrLOcV3GAHkYvnVFQSqdE0avrge/jsD7WdA6x8qQFNRugxQcxDJa2l0+C+BH
|
|
18
|
+
SbU9TimGwhA1yusHHfuz9LAXks5IQ48+2e6Pulh7iThXPJUnIKqKZUN5HhL79aaK
|
|
19
|
+
vrZKIgSfVhwE5PMPXWZ+Ij5IRf74PLIUn1Er75qhBXlDJ4vF8y8/3owURNC1XiUB
|
|
20
|
+
DGElwV/LYNoqAQei4oixe4EAxPGvFi11pgHiGuRxuWckA88y6ZHLt6urfAY9sCkj
|
|
21
|
+
kF+2dc2yS3j7lD+SYAaV5LQYYjePP1CYvxCZ7HHRKqthHopxY1hsK2tBtni3f7/c
|
|
22
|
+
UwIDAQAB
|
|
23
|
+
-----END PUBLIC KEY-----`;
|
|
24
|
+
const PLUGIN_ID = 'vendure-plugin-geo-block';
|
|
25
|
+
const REVOCATION_URL = process.env.HULO_LICENCE_REVOCATION_URL
|
|
26
|
+
|| 'https://elite.charity/licence/revoked.json';
|
|
27
|
+
let cachedOptions = { publicBaseUrl: 'http://localhost:3000' };
|
|
28
|
+
function getOptions() { return cachedOptions; }
|
|
29
|
+
/**
|
|
30
|
+
* `@huloglobal/vendure-plugin-geo-block`
|
|
31
|
+
*
|
|
32
|
+
* Per-channel geo-restriction for Vendure storefronts. The plugin owns
|
|
33
|
+
* a flat `/geo-block/site-config` endpoint the storefront polls (cached
|
|
34
|
+
* client-side) plus an admin page for configuring region presets,
|
|
35
|
+
* extra allowed countries, denylist, and UK-region subfilter.
|
|
36
|
+
*
|
|
37
|
+
* Add to your Vendure config:
|
|
38
|
+
*
|
|
39
|
+
* ```ts
|
|
40
|
+
* import { GeoBlockPlugin } from '@huloglobal/vendure-plugin-geo-block';
|
|
41
|
+
*
|
|
42
|
+
* export const config: VendureConfig = {
|
|
43
|
+
* plugins: [
|
|
44
|
+
* GeoBlockPlugin.init({
|
|
45
|
+
* publicBaseUrl: 'https://shop.example.com',
|
|
46
|
+
* licenceKey: process.env.HULO_LICENCE_KEY,
|
|
47
|
+
* }),
|
|
48
|
+
* ],
|
|
49
|
+
* };
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
let GeoBlockPlugin = GeoBlockPlugin_1 = class GeoBlockPlugin {
|
|
53
|
+
static init(options) {
|
|
54
|
+
cachedOptions = options;
|
|
55
|
+
if (!GeoBlockPlugin_1.revocation) {
|
|
56
|
+
GeoBlockPlugin_1.revocation = new vendure_licence_sdk_1.RevocationChecker(REVOCATION_URL);
|
|
57
|
+
GeoBlockPlugin_1.revocation.start();
|
|
58
|
+
}
|
|
59
|
+
const host = (options.publicBaseUrl || '')
|
|
60
|
+
.replace(/^https?:\/\//, '').replace(/\/.*$/, '');
|
|
61
|
+
const status = (0, vendure_licence_sdk_1.verifyLicence)({
|
|
62
|
+
licenceKey: options.licenceKey,
|
|
63
|
+
pluginId: PLUGIN_ID,
|
|
64
|
+
host,
|
|
65
|
+
publicKey: HULO_PUBLIC_KEY,
|
|
66
|
+
revokedIds: GeoBlockPlugin_1.revocation.getRevokedIds(),
|
|
67
|
+
});
|
|
68
|
+
if (!status.valid) {
|
|
69
|
+
// eslint-disable-next-line no-console
|
|
70
|
+
console.warn(`[@huloglobal/vendure-plugin-geo-block] ${status.message}` +
|
|
71
|
+
` — Running in unlicensed mode (settings still saveable, but the public endpoint always reports enabled=false). Purchase a key at https://elite-software.co.uk/licence/buy/${PLUGIN_ID}`);
|
|
72
|
+
}
|
|
73
|
+
return GeoBlockPlugin_1;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
exports.GeoBlockPlugin = GeoBlockPlugin;
|
|
77
|
+
GeoBlockPlugin.revocation = null;
|
|
78
|
+
GeoBlockPlugin.uiExtensions = {
|
|
79
|
+
extensionPath: __dirname + '/../ui',
|
|
80
|
+
ngModules: [
|
|
81
|
+
{
|
|
82
|
+
type: 'lazy',
|
|
83
|
+
route: 'geo-block',
|
|
84
|
+
ngModuleFileName: 'geo-block.module.ts',
|
|
85
|
+
ngModuleName: 'GeoBlockModule',
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
};
|
|
89
|
+
exports.GeoBlockPlugin = GeoBlockPlugin = GeoBlockPlugin_1 = __decorate([
|
|
90
|
+
(0, core_1.VendurePlugin)({
|
|
91
|
+
imports: [core_1.PluginCommonModule],
|
|
92
|
+
controllers: [geo_block_controller_1.GeoBlockController],
|
|
93
|
+
compatibility: '^3.0.0',
|
|
94
|
+
configuration: config => {
|
|
95
|
+
config.customFields.Channel = (config.customFields.Channel || []).concat([
|
|
96
|
+
{
|
|
97
|
+
name: 'geoBlockEnabled', type: 'boolean', public: true, defaultValue: false,
|
|
98
|
+
label: [{ languageCode: core_1.LanguageCode.en, value: 'Site: Geo-block enabled' }],
|
|
99
|
+
description: [{ languageCode: core_1.LanguageCode.en, value: 'When on, visitors outside the allowed countries (and UK regions, if GB is allowed) see a "down for maintenance" page instead of the storefront.' }],
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: 'geoBlockAllowedRegions', type: 'string', list: true, public: true,
|
|
103
|
+
defaultValue: [],
|
|
104
|
+
label: [{ languageCode: core_1.LanguageCode.en, value: 'Site: Geo-block allowed regions (presets)' }],
|
|
105
|
+
description: [{ languageCode: core_1.LanguageCode.en, value: 'One-click region presets. Combine with extra/blocked countries below.' }],
|
|
106
|
+
options: [
|
|
107
|
+
{ value: 'UK_ONLY', label: [{ languageCode: core_1.LanguageCode.en, value: 'United Kingdom only' }] },
|
|
108
|
+
{ value: 'BRITISH_ISLES', label: [{ languageCode: core_1.LanguageCode.en, value: 'British Isles (GB, IE, IoM, CI, Faroes)' }] },
|
|
109
|
+
{ value: 'EU', label: [{ languageCode: core_1.LanguageCode.en, value: 'European Union (27)' }] },
|
|
110
|
+
{ value: 'EEA', label: [{ languageCode: core_1.LanguageCode.en, value: 'EEA (EU + IS, LI, NO)' }] },
|
|
111
|
+
{ value: 'EUROPE', label: [{ languageCode: core_1.LanguageCode.en, value: 'Whole Europe (incl. UK, RU, UA, micro-states)' }] },
|
|
112
|
+
{ value: 'NORTH_AMERICA', label: [{ languageCode: core_1.LanguageCode.en, value: 'North America (US, CA, MX)' }] },
|
|
113
|
+
{ value: 'OCEANIA', label: [{ languageCode: core_1.LanguageCode.en, value: 'Oceania (AU, NZ)' }] },
|
|
114
|
+
{ value: 'WORLDWIDE', label: [{ languageCode: core_1.LanguageCode.en, value: 'Worldwide — only blocked countries excluded' }] },
|
|
115
|
+
],
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
name: 'geoBlockAllowedCountries', type: 'string', list: true, public: true,
|
|
119
|
+
defaultValue: [],
|
|
120
|
+
label: [{ languageCode: core_1.LanguageCode.en, value: 'Site: Extra allowed countries (ISO 3166-1 alpha-2)' }],
|
|
121
|
+
description: [{ languageCode: core_1.LanguageCode.en, value: 'Countries allowed on top of the selected regions. Use ISO codes (GB, IE, FR, US…).' }],
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: 'geoBlockBlockedCountries', type: 'string', list: true, public: true,
|
|
125
|
+
defaultValue: [],
|
|
126
|
+
label: [{ languageCode: core_1.LanguageCode.en, value: 'Site: Always-blocked countries' }],
|
|
127
|
+
description: [{ languageCode: core_1.LanguageCode.en, value: 'Subtracted from the resolved allow-list. Useful for blocking specific countries inside a region you otherwise allow.' }],
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: 'geoBlockAllowedGbRegions', type: 'string', list: true, public: true,
|
|
131
|
+
defaultValue: [],
|
|
132
|
+
label: [{ languageCode: core_1.LanguageCode.en, value: 'Site: Geo-block allowed UK regions' }],
|
|
133
|
+
description: [{ languageCode: core_1.LanguageCode.en, value: 'When GB is resolved as allowed, additionally restrict to ENG / WLS / SCT / NIR. Empty = whole UK allowed.' }],
|
|
134
|
+
},
|
|
135
|
+
]);
|
|
136
|
+
return config;
|
|
137
|
+
},
|
|
138
|
+
})
|
|
139
|
+
], GeoBlockPlugin);
|
|
140
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Request } from 'express';
|
|
2
|
+
/**
|
|
3
|
+
* Reverse-proxy aware visitor IP extraction.
|
|
4
|
+
*
|
|
5
|
+
* Order of precedence:
|
|
6
|
+
* 1. Cloudflare's `CF-Connecting-IP` (always the real client IP,
|
|
7
|
+
* regardless of how many proxies sit in front of the worker).
|
|
8
|
+
* 2. `True-Client-IP` (Akamai / Cloudflare Enterprise).
|
|
9
|
+
* 3. `X-Real-IP` (nginx / Caddy default when proxying).
|
|
10
|
+
* 4. First entry in `X-Forwarded-For` (RFC 7239 ancestor; the
|
|
11
|
+
* left-most entry is the original client when the upstream proxy
|
|
12
|
+
* is trusted).
|
|
13
|
+
* 5. Express's `req.ip` — only useful when `app.set('trust proxy', ...)`
|
|
14
|
+
* has been set on the Vendure host, otherwise this is the socket
|
|
15
|
+
* address of the last hop.
|
|
16
|
+
*
|
|
17
|
+
* Returns `null` if none of the headers are populated and `req.ip`
|
|
18
|
+
* isn't available — the caller should treat this as "unknown" and
|
|
19
|
+
* skip IP-dependent enrichment rather than fail.
|
|
20
|
+
*/
|
|
21
|
+
export declare function getRealIp(req: Request): string | null;
|
|
22
|
+
/**
|
|
23
|
+
* Cloudflare / Akamai populate the visitor's resolved country on the
|
|
24
|
+
* inbound request when the corresponding feature is enabled. Reading
|
|
25
|
+
* the upstream value avoids a per-request GeoIP lookup. Returns the
|
|
26
|
+
* ISO 3166-1 alpha-2 country code or `null` if no proxy header is
|
|
27
|
+
* present.
|
|
28
|
+
*/
|
|
29
|
+
export declare function getResolvedCountry(req: Request): string | null;
|
|
30
|
+
/**
|
|
31
|
+
* Cloudflare's `cf-region-code` carries the ISO 3166-2 subdivision
|
|
32
|
+
* (e.g. `ENG`, `SCT`, `CA`) when the "Send subdivision data" option is
|
|
33
|
+
* enabled in the dashboard. Returns the bare code without the country
|
|
34
|
+
* prefix, or `null` if unavailable.
|
|
35
|
+
*/
|
|
36
|
+
export declare function getResolvedRegion(req: Request): string | null;
|
|
37
|
+
//# sourceMappingURL=proxy-headers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-headers.d.ts","sourceRoot":"","sources":["../src/proxy-headers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAkBrD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAe9D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAK7D"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getRealIp = getRealIp;
|
|
4
|
+
exports.getResolvedCountry = getResolvedCountry;
|
|
5
|
+
exports.getResolvedRegion = getResolvedRegion;
|
|
6
|
+
/**
|
|
7
|
+
* Reverse-proxy aware visitor IP extraction.
|
|
8
|
+
*
|
|
9
|
+
* Order of precedence:
|
|
10
|
+
* 1. Cloudflare's `CF-Connecting-IP` (always the real client IP,
|
|
11
|
+
* regardless of how many proxies sit in front of the worker).
|
|
12
|
+
* 2. `True-Client-IP` (Akamai / Cloudflare Enterprise).
|
|
13
|
+
* 3. `X-Real-IP` (nginx / Caddy default when proxying).
|
|
14
|
+
* 4. First entry in `X-Forwarded-For` (RFC 7239 ancestor; the
|
|
15
|
+
* left-most entry is the original client when the upstream proxy
|
|
16
|
+
* is trusted).
|
|
17
|
+
* 5. Express's `req.ip` — only useful when `app.set('trust proxy', ...)`
|
|
18
|
+
* has been set on the Vendure host, otherwise this is the socket
|
|
19
|
+
* address of the last hop.
|
|
20
|
+
*
|
|
21
|
+
* Returns `null` if none of the headers are populated and `req.ip`
|
|
22
|
+
* isn't available — the caller should treat this as "unknown" and
|
|
23
|
+
* skip IP-dependent enrichment rather than fail.
|
|
24
|
+
*/
|
|
25
|
+
function getRealIp(req) {
|
|
26
|
+
var _a;
|
|
27
|
+
const headers = req.headers || {};
|
|
28
|
+
const cfIp = String(headers['cf-connecting-ip'] || '').trim();
|
|
29
|
+
if (cfIp)
|
|
30
|
+
return cfIp;
|
|
31
|
+
const trueClient = String(headers['true-client-ip'] || '').trim();
|
|
32
|
+
if (trueClient)
|
|
33
|
+
return trueClient;
|
|
34
|
+
const realIp = String(headers['x-real-ip'] || '').trim();
|
|
35
|
+
if (realIp)
|
|
36
|
+
return realIp;
|
|
37
|
+
const xff = String(headers['x-forwarded-for'] || '').trim();
|
|
38
|
+
if (xff) {
|
|
39
|
+
const first = (_a = xff.split(',')[0]) === null || _a === void 0 ? void 0 : _a.trim();
|
|
40
|
+
if (first)
|
|
41
|
+
return first;
|
|
42
|
+
}
|
|
43
|
+
return req.ip || null;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Cloudflare / Akamai populate the visitor's resolved country on the
|
|
47
|
+
* inbound request when the corresponding feature is enabled. Reading
|
|
48
|
+
* the upstream value avoids a per-request GeoIP lookup. Returns the
|
|
49
|
+
* ISO 3166-1 alpha-2 country code or `null` if no proxy header is
|
|
50
|
+
* present.
|
|
51
|
+
*/
|
|
52
|
+
function getResolvedCountry(req) {
|
|
53
|
+
const headers = req.headers || {};
|
|
54
|
+
const cf = String(headers['cf-ipcountry'] || '').trim().toUpperCase();
|
|
55
|
+
if (cf && cf !== 'XX' && cf !== 'T1')
|
|
56
|
+
return cf;
|
|
57
|
+
const akamai = String(headers['x-akamai-edgescape'] || '').trim();
|
|
58
|
+
if (akamai) {
|
|
59
|
+
const m = akamai.match(/country_code=([A-Z]{2})/i);
|
|
60
|
+
if (m)
|
|
61
|
+
return m[1].toUpperCase();
|
|
62
|
+
}
|
|
63
|
+
const fastly = String(headers['x-country-code'] || '').trim().toUpperCase();
|
|
64
|
+
if (fastly && /^[A-Z]{2}$/.test(fastly))
|
|
65
|
+
return fastly;
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Cloudflare's `cf-region-code` carries the ISO 3166-2 subdivision
|
|
70
|
+
* (e.g. `ENG`, `SCT`, `CA`) when the "Send subdivision data" option is
|
|
71
|
+
* enabled in the dashboard. Returns the bare code without the country
|
|
72
|
+
* prefix, or `null` if unavailable.
|
|
73
|
+
*/
|
|
74
|
+
function getResolvedRegion(req) {
|
|
75
|
+
const headers = req.headers || {};
|
|
76
|
+
const cf = String(headers['cf-region-code'] || '').trim().toUpperCase();
|
|
77
|
+
if (cf && /^[A-Z0-9]{1,4}$/.test(cf))
|
|
78
|
+
return cf;
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=proxy-headers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-headers.js","sourceRoot":"","sources":["../src/proxy-headers.ts"],"names":[],"mappings":";;AAqBA,8BAkBC;AASD,gDAeC;AAQD,8CAKC;AA1ED;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAgB,SAAS,CAAC,GAAY;;IAClC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC;IAClC,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9D,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IAEtB,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAClE,IAAI,UAAU;QAAE,OAAO,UAAU,CAAC;IAElC,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACzD,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5D,IAAI,GAAG,EAAE,CAAC;QACN,MAAM,KAAK,GAAG,MAAA,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,0CAAE,IAAI,EAAE,CAAC;QACxC,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;IAC5B,CAAC;IAED,OAAQ,GAAW,CAAC,EAAE,IAAI,IAAI,CAAC;AACnC,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,kBAAkB,CAAC,GAAY;IAC3C,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC;IAClC,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACtE,IAAI,EAAE,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IAEhD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAClE,IAAI,MAAM,EAAE,CAAC;QACT,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;QACnD,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACrC,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC5E,IAAI,MAAM,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAEvD,OAAO,IAAI,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,iBAAiB,CAAC,GAAY;IAC1C,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC;IAClC,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACxE,IAAI,EAAE,IAAI,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,EAAE,CAAC;IAChD,OAAO,IAAI,CAAC;AAChB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@huloglobal/vendure-plugin-geo-block",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Geo-restrict your Vendure storefront by country, UK region or curated region presets (EU, EEA, British Isles, Europe, North America, Oceania, Worldwide-with-denylist). Per-channel settings exposed as Channel custom fields plus a dedicated admin page with a live preview of the resolved allow-list.",
|
|
5
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
6
|
+
"author": "Wayne Garrison <wayne@garrison.me.uk>",
|
|
7
|
+
"homepage": "https://github.com/exceeded/vendure-plugin-geo-block",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/exceeded/vendure-plugin-geo-block.git"
|
|
11
|
+
},
|
|
12
|
+
"main": "dist/index.js",
|
|
13
|
+
"types": "dist/index.d.ts",
|
|
14
|
+
"files": ["dist", "ui", "README.md", "CHANGELOG.md", "LICENSE"],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc -p tsconfig.json",
|
|
17
|
+
"prepublishOnly": "yarn build"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@huloglobal/vendure-licence-sdk": "^0.1.0"
|
|
21
|
+
},
|
|
22
|
+
"peerDependencies": {
|
|
23
|
+
"@vendure/core": ">=3.0.0",
|
|
24
|
+
"@nestjs/common": ">=10.0.0",
|
|
25
|
+
"typeorm": ">=0.3.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@huloglobal/vendure-licence-sdk": "^0.1.0",
|
|
29
|
+
"@nestjs/common": "^10.0.0",
|
|
30
|
+
"@vendure/core": "^3.6.0",
|
|
31
|
+
"typeorm": "^0.3.0",
|
|
32
|
+
"typescript": "^5.4.0"
|
|
33
|
+
},
|
|
34
|
+
"keywords": [
|
|
35
|
+
"vendure",
|
|
36
|
+
"vendure-plugin",
|
|
37
|
+
"geo-block",
|
|
38
|
+
"geo-restriction",
|
|
39
|
+
"geoip"
|
|
40
|
+
]
|
|
41
|
+
}
|