@swetrix/captcha 2.0.2 → 2.3.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.
Files changed (46) hide show
  1. package/README.md +72 -5
  2. package/dist/captcha-loader.cjs +333 -0
  3. package/dist/captcha-loader.cjs.map +1 -0
  4. package/dist/captcha-loader.esm.js +327 -0
  5. package/dist/captcha-loader.esm.js.map +1 -0
  6. package/dist/captcha-loader.js +1 -1
  7. package/dist/captcha-loader.js.map +1 -1
  8. package/dist/captcha.js +1 -1
  9. package/dist/captcha.js.map +1 -1
  10. package/dist/esnext/captcha-loader.d.ts +10 -0
  11. package/dist/esnext/captcha-loader.js +315 -0
  12. package/dist/esnext/captcha-loader.js.map +1 -0
  13. package/dist/esnext/captcha.d.ts +10 -0
  14. package/dist/esnext/captcha.js +491 -0
  15. package/dist/esnext/captcha.js.map +1 -0
  16. package/dist/esnext/i18n.d.ts +22 -0
  17. package/dist/esnext/i18n.js +110 -0
  18. package/dist/esnext/i18n.js.map +1 -0
  19. package/dist/esnext/index.d.ts +7 -0
  20. package/dist/esnext/index.js +7 -0
  21. package/dist/esnext/index.js.map +1 -0
  22. package/dist/esnext/logger.d.ts +6 -0
  23. package/dist/esnext/logger.js +8 -0
  24. package/dist/esnext/logger.js.map +1 -0
  25. package/dist/esnext/pow-worker.d.ts +1 -0
  26. package/dist/esnext/pow-worker.js +127 -0
  27. package/dist/esnext/pow-worker.js.map +1 -0
  28. package/dist/pages/dark.html +461 -276
  29. package/dist/pages/light.html +463 -278
  30. package/dist/pages/test.html +26 -27
  31. package/package.json +58 -32
  32. package/.nvmrc +0 -1
  33. package/.prettierrc.js +0 -13
  34. package/dist/assets/logo_blue.png +0 -0
  35. package/dist/assets/logo_white.png +0 -0
  36. package/rollup.config.mjs +0 -83
  37. package/src/assets/logo_blue.png +0 -0
  38. package/src/assets/logo_white.png +0 -0
  39. package/src/captcha-loader.ts +0 -212
  40. package/src/captcha.ts +0 -358
  41. package/src/pages/dark.html +0 -284
  42. package/src/pages/light.html +0 -286
  43. package/src/pages/test.html +0 -33
  44. package/src/pow-worker.ts +0 -178
  45. package/tsconfig.esnext.json +0 -15
  46. package/tsconfig.json +0 -14
@@ -1,33 +1,32 @@
1
1
  <!-- Generate a form with several inputs -->
2
2
  <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>Test</title>
6
+ <style>
7
+ .form {
8
+ display: flex;
9
+ flex-direction: column;
10
+ width: 400px;
11
+ margin: 0 auto;
12
+ }
3
13
 
4
- <head>
5
- <meta charset="utf-8">
6
- <title>Test</title>
7
- <style>
8
- .form {
9
- display: flex;
10
- flex-direction: column;
11
- width: 400px;
12
- margin: 0 auto;
13
- }
14
+ .form > * {
15
+ margin-top: 10px;
16
+ }
17
+ </style>
14
18
 
15
- .form>* {
16
- margin-top: 10px;
17
- }
18
- </style>
19
-
20
- <script src="../../dist/captcha-loader.js" defer></script>
21
- </head>
22
-
23
- <body>
24
- <form class="form" action="test.html" method="post">
25
- <input type="text" name="name" value="name">
26
- <input type="text" name="email" value="email">
27
- <input type="number" name="number" value="number">
28
- <div class="swecaptcha" data-project-id="AP00000000000" data-theme="light"></div>
29
- <input type="submit" value="Submit">
30
- </form>
31
- </body>
19
+ <script src="../../dist/captcha-loader.js" defer></script>
20
+ </head>
32
21
 
22
+ <body>
23
+ <form class="form" action="test.html" method="post">
24
+ <input type="text" name="name" value="name" />
25
+ <input type="text" name="email" value="email" />
26
+ <input type="number" name="number" value="number" />
27
+ <div class="swecaptcha" data-project-id="AP00000000000" data-theme="auto"></div>
28
+ <!-- <div class="swecaptcha" data-project-id="79eF2Z9rNNvv" data-theme="auto"></div> -->
29
+ <input type="submit" value="Submit" />
30
+ </form>
31
+ </body>
33
32
  </html>
package/package.json CHANGED
@@ -1,53 +1,79 @@
1
1
  {
2
2
  "name": "@swetrix/captcha",
3
- "version": "2.0.2",
3
+ "version": "2.3.0",
4
4
  "description": "Swetrix CAPTCHA",
5
+ "keywords": [
6
+ "analytics",
7
+ "metrics",
8
+ "monitoring",
9
+ "privacy",
10
+ "swetrix"
11
+ ],
12
+ "homepage": "https://swetrix.com/captcha",
13
+ "bugs": {
14
+ "url": "https://github.com/Swetrix/swetrix/issues"
15
+ },
16
+ "license": "MIT",
17
+ "author": "Swetrix Ltd <contact@swetrix.com>",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/Swetrix/swetrix.git"
21
+ },
22
+ "funding": "https://github.com/sponsors/Swetrix",
5
23
  "type": "module",
6
- "captchaloader": "dist/captcha-loader.js",
7
- "captcha": "dist/captcha.js",
8
- "esnext": "dist/esnext/index.js",
24
+ "main": "dist/captcha-loader.cjs",
25
+ "module": "dist/captcha-loader.esm.js",
26
+ "browser": "dist/captcha-loader.js",
27
+ "unpkg": "dist/captcha-loader.js",
28
+ "jsdelivr": "dist/captcha-loader.js",
9
29
  "typings": "dist/esnext/index.d.ts",
30
+ "esnext": "dist/captcha-loader.esm.js",
10
31
  "exports": {
11
32
  ".": {
12
- "import": "./dist/esnext/index.js",
13
- "require": "./dist/captcha.cjs.js",
14
33
  "types": "./dist/esnext/index.d.ts",
15
- "default": "./dist/captcha.js"
16
- }
34
+ "import": "./dist/captcha-loader.esm.js",
35
+ "require": "./dist/captcha-loader.cjs",
36
+ "default": "./dist/captcha-loader.js"
37
+ },
38
+ "./captcha-loader": {
39
+ "types": "./dist/esnext/index.d.ts",
40
+ "import": "./dist/captcha-loader.esm.js",
41
+ "require": "./dist/captcha-loader.cjs",
42
+ "default": "./dist/captcha-loader.js"
43
+ },
44
+ "./dist/captcha-loader.js": "./dist/captcha-loader.js",
45
+ "./dist/captcha.js": "./dist/captcha.js",
46
+ "./dist/pow-worker.js": "./dist/pow-worker.js",
47
+ "./dist/pages/light.html": "./dist/pages/light.html",
48
+ "./dist/pages/dark.html": "./dist/pages/dark.html",
49
+ "./package.json": "./package.json"
50
+ },
51
+ "files": [
52
+ "dist",
53
+ "README.md",
54
+ "LICENSE"
55
+ ],
56
+ "publishConfig": {
57
+ "access": "public"
17
58
  },
18
59
  "scripts": {
19
60
  "prebuild": "rimraf dist",
61
+ "prepack": "npm run build",
20
62
  "prepublish": "npm run build",
21
- "build": "rollup -c",
63
+ "build": "rollup -c && npm run tsc",
22
64
  "start": "rollup -c -w",
23
65
  "tsc": "tsc -p tsconfig.esnext.json"
24
66
  },
25
- "keywords": [
26
- "swetrix",
27
- "analytics",
28
- "monitoring",
29
- "metrics",
30
- "privacy"
31
- ],
32
- "repository": {
33
- "type": "git",
34
- "url": "git+https://github.com/Swetrix/swetrix-captcha.git"
35
- },
36
- "author": "Swetrix Ltd <contact@swetrix.com>",
37
- "license": "MIT",
38
- "bugs": {
39
- "url": "https://github.com/Swetrix/swetrix-captcha/issues"
40
- },
41
- "homepage": "https://swetrix.com/captcha",
42
67
  "devDependencies": {
43
- "@rollup/plugin-terser": "^0.4.4",
68
+ "@rollup/plugin-terser": "^1.0.0",
44
69
  "@rollup/plugin-typescript": "^12.3.0",
45
- "@types/node": "^22.15.21",
70
+ "@types/node": "^25.9.0",
71
+ "rimraf": "^6.1.3",
72
+ "rollup": "^4.60.4",
46
73
  "rollup-plugin-copy": "^3.5.0",
47
74
  "tslib": "^2.8.1",
48
- "@blaumaus/rollup-plugin-uglify": "^7.0.1",
49
- "rimraf": "^5.0.7",
50
- "rollup": "^4.54.0",
51
75
  "typescript": "^5.9.3"
52
- }
76
+ },
77
+ "captcha": "dist/captcha.js",
78
+ "captchaloader": "dist/captcha-loader.js"
53
79
  }
package/.nvmrc DELETED
@@ -1 +0,0 @@
1
- 16.19.1
package/.prettierrc.js DELETED
@@ -1,13 +0,0 @@
1
- module.exports = {
2
- printWidth: 120, // max 120 chars in line, code is easy to read
3
- useTabs: false, // use spaces instead of tabs
4
- tabWidth: 2, // "visual width" of of the "tab"
5
- trailingComma: 'all', // add trailing commas in objects, arrays, etc.
6
- semi: false, // Only add semicolons at the beginning of lines that may introduce ASI failures
7
- singleQuote: true, // '' for stings instead of ""
8
- bracketSpacing: true, // import { some } ... instead of import {some} ...
9
- arrowParens: 'always', // braces even for single param in arrow functions (a) => { }
10
- jsxSingleQuote: true, // '' for react props
11
- bracketSameLine: false, // pretty JSX
12
- endOfLine: 'lf', // 'lf' for linux, 'crlf' for windows, we need to use 'lf' for git
13
- }
Binary file
Binary file
package/rollup.config.mjs DELETED
@@ -1,83 +0,0 @@
1
- // import commonjs from '@rollup/plugin-commonjs'
2
- import copy from 'rollup-plugin-copy'
3
- import typescript from '@rollup/plugin-typescript'
4
- import terser from '@rollup/plugin-terser'
5
- import pkg from './package.json' with { type: 'json' }
6
- import { createRequire } from 'node:module'
7
-
8
- const CAPTCHA_PATH = 'src/captcha.ts'
9
- const CAPTCHA_LOADER_PATH = 'src/captcha-loader.ts'
10
- const POW_WORKER_PATH = 'src/pow-worker.ts'
11
-
12
- const require = createRequire(import.meta.url)
13
-
14
- export default [
15
- {
16
- input: CAPTCHA_PATH,
17
- output: [
18
- {
19
- file: pkg.captcha,
20
- format: 'umd',
21
- name: 'captcha',
22
- sourcemap: true,
23
- },
24
- ],
25
- plugins: [
26
- typescript({
27
- outDir: './dist',
28
- sourceMap: true,
29
- tslib: require.resolve('tslib'),
30
- }),
31
-
32
- // copying assets
33
- copy({
34
- targets: [
35
- { src: 'src/assets/*', dest: 'dist/assets' },
36
- { src: 'src/pages/*', dest: 'dist/pages' },
37
- ],
38
- }),
39
- terser(),
40
- // commonjs(),
41
- ],
42
- },
43
- {
44
- input: CAPTCHA_LOADER_PATH,
45
- output: [
46
- {
47
- file: pkg.captchaloader,
48
- format: 'umd',
49
- name: 'captcha-loader',
50
- sourcemap: true,
51
- },
52
- ],
53
- plugins: [
54
- typescript({
55
- outDir: './dist',
56
- sourceMap: true,
57
- tslib: require.resolve('tslib'),
58
- }),
59
- terser(),
60
- // commonjs(),
61
- ],
62
- },
63
- {
64
- input: POW_WORKER_PATH,
65
- output: [
66
- {
67
- file: 'dist/pow-worker.js',
68
- format: 'iife',
69
- name: 'powWorker',
70
- sourcemap: true,
71
- },
72
- ],
73
- plugins: [
74
- typescript({
75
- outDir: './dist',
76
- sourceMap: true,
77
- tslib: require.resolve('tslib'),
78
- }),
79
- terser(),
80
- // commonjs(),
81
- ],
82
- },
83
- ]
Binary file
Binary file
@@ -1,212 +0,0 @@
1
- // @ts-ignore
2
- const isDevelopment = window.__SWETRIX_CAPTCHA_DEV || false
3
-
4
- const CAPTCHA_SELECTOR = '.swecaptcha'
5
- const LIGHT_CAPTCHA_IFRAME_URL = isDevelopment ? './light.html' : 'https://cap.swetrix.com/pages/light'
6
- const DARK_CAPTCHA_IFRAME_URL = isDevelopment ? './dark.html' : 'https://cap.swetrix.com/pages/dark'
7
- const DEFAULT_RESPONSE_INPUT_NAME = 'swetrix-captcha-response'
8
- const MESSAGE_IDENTIFIER = 'swetrix-captcha'
9
- const ID_PREFIX = 'swetrix-captcha-'
10
- const THEMES = ['light', 'dark']
11
- const PID_REGEX = /^(?!.*--)[a-zA-Z0-9-]{12}$/
12
-
13
- enum LOG_ACTIONS {
14
- log = 'log',
15
- error = 'error',
16
- warn = 'warn',
17
- info = 'info',
18
- }
19
-
20
- const DUMMY_PIDS = ['AP00000000000', 'FAIL000000000']
21
-
22
- const isValidPID = (pid: string) => DUMMY_PIDS.includes(pid) || PID_REGEX.test(pid)
23
-
24
- const FRAME_HEIGHT = '66px'
25
-
26
- const getFrameID = (cid: string) => `${cid}-frame`
27
-
28
- const ids: string[] = []
29
-
30
- const log = (status: LOG_ACTIONS, text: string) => {
31
- console[status](`[Swetrix Captcha] ${text}`)
32
- }
33
-
34
- const appendParamsToURL = (url: string, params: any) => {
35
- const queryString = Object.keys(params)
36
- .map((key) => {
37
- return `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`
38
- })
39
- .join('&')
40
-
41
- return `${url}?${queryString}`
42
- }
43
-
44
- const renderCaptcha = (container: Element, params: any) => {
45
- const cid = generateRandomID()
46
- const cParams = {
47
- ...params,
48
- cid, // CAPTCHA ID
49
- }
50
-
51
- const frame = generateCaptchaFrame(cParams)
52
- const input = generateHiddenInput(cParams)
53
-
54
- container.appendChild(frame)
55
- container.appendChild(input)
56
- }
57
-
58
- const generateRandomID = (): string => {
59
- const randomID = ID_PREFIX + Math.random().toString(36).substr(2, 6)
60
-
61
- if (ids.includes(randomID)) {
62
- return generateRandomID()
63
- }
64
-
65
- ids.push(randomID)
66
-
67
- return randomID
68
- }
69
-
70
- const postMessageCallback = (pmEvent: MessageEvent) => {
71
- // TODO: Validate origin
72
-
73
- const { data } = pmEvent
74
-
75
- if (!data) {
76
- return
77
- }
78
-
79
- const { type, cid, event } = data
80
-
81
- if (type !== MESSAGE_IDENTIFIER) {
82
- return
83
- }
84
-
85
- if (!cid || !ids.includes(cid)) {
86
- return
87
- }
88
-
89
- const input = document.getElementById(cid)
90
- const inputExists = input !== null
91
-
92
- switch (event) {
93
- case 'success': {
94
- const { token } = data
95
-
96
- if (!inputExists) {
97
- log(LOG_ACTIONS.error, '[PM -> success] Input element does not exist.')
98
- return
99
- }
100
-
101
- // @ts-ignore
102
- input.value = token
103
-
104
- break
105
- }
106
-
107
- case 'failure': {
108
- if (!inputExists) {
109
- log(LOG_ACTIONS.error, '[PM -> failure] Input element does not exist.')
110
- return
111
- }
112
-
113
- // @ts-ignore
114
- input.value = ''
115
-
116
- break
117
- }
118
-
119
- case 'tokenExpired': {
120
- if (!inputExists) {
121
- log(LOG_ACTIONS.error, '[PM -> failure] Input element does not exist.')
122
- return
123
- }
124
-
125
- // @ts-ignore
126
- input.value = ''
127
-
128
- break
129
- }
130
- }
131
- }
132
-
133
- const generateCaptchaFrame = (params: any) => {
134
- const { theme } = params
135
- const captchaFrame = document.createElement('iframe')
136
-
137
- captchaFrame.id = getFrameID(params.cid)
138
- captchaFrame.src =
139
- theme === 'dark'
140
- ? appendParamsToURL(DARK_CAPTCHA_IFRAME_URL, params)
141
- : appendParamsToURL(LIGHT_CAPTCHA_IFRAME_URL, params)
142
- captchaFrame.style.height = FRAME_HEIGHT
143
- captchaFrame.title = 'Swetrix Captcha'
144
- captchaFrame.style.border = 'none'
145
- captchaFrame.style.width = '302px'
146
- captchaFrame.style.overflow = 'visible'
147
-
148
- return captchaFrame
149
- }
150
-
151
- const generateHiddenInput = (params: any) => {
152
- const { cid } = params
153
- const input = document.createElement('input')
154
-
155
- input.type = 'hidden'
156
- input.name = params.respName
157
- input.value = ''
158
- input.id = cid
159
-
160
- return input
161
- }
162
-
163
- const validateParams = (params: any) => {
164
- const { theme, pid } = params
165
-
166
- if (theme && !THEMES.includes(theme)) {
167
- log(LOG_ACTIONS.error, `Invalid data-theme parameter: ${theme}`)
168
- return false
169
- }
170
-
171
- if (!pid || !isValidPID(pid)) {
172
- log(LOG_ACTIONS.error, `Invalid data-project-id parameter: ${pid}`)
173
- return false
174
- }
175
-
176
- return true
177
- }
178
-
179
- const parseParams = (container: Element): object => ({
180
- pid: container.getAttribute('data-project-id'),
181
- respName: container.getAttribute('data-response-input-name') || DEFAULT_RESPONSE_INPUT_NAME,
182
- theme: container.getAttribute('data-theme'),
183
- })
184
-
185
- const main = (forced = false) => {
186
- if (!forced && 'swecaptcha' in window) {
187
- log(LOG_ACTIONS.warn, 'Captcha is already loaded.')
188
- }
189
-
190
- // TODO: Add some callbacks here
191
- // @ts-ignore
192
- window.swecaptcha = true
193
- window.addEventListener('message', postMessageCallback)
194
-
195
- const containers = Array.from(document.querySelectorAll(CAPTCHA_SELECTOR))
196
-
197
- for (const container of containers) {
198
- const params = parseParams(container)
199
-
200
- if (!validateParams(params)) {
201
- log(LOG_ACTIONS.error, 'Aborting captcha rendering due to invalid parameters.')
202
- return
203
- }
204
-
205
- renderCaptcha(container, params)
206
- }
207
- }
208
-
209
- // @ts-ignore
210
- window.swetrixCaptchaForceLoad = () => main(true)
211
-
212
- document.addEventListener('DOMContentLoaded', () => main())