fix: 修复配额说明重复和undefined问题
- 在editStorageForm中初始化oss_storage_quota_value和oss_quota_unit - 删除重复的旧配额说明块,保留新的当前配额设置显示 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
35
backend/node_modules/svg-captcha/HISTORY.md
generated
vendored
Normal file
35
backend/node_modules/svg-captcha/HISTORY.md
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
1.4.0 / 2019-05-03
|
||||
===================
|
||||
|
||||
* Fixed #33 https://github.com/lemonce/svg-captcha/pull/33
|
||||
|
||||
1.3.11 / 2017-08-23
|
||||
===================
|
||||
|
||||
* Fix typescript definition
|
||||
|
||||
1.3.9 / 2017-07-23
|
||||
===================
|
||||
|
||||
* Fix charSet options
|
||||
|
||||
1.3.8 / 2017-07-20
|
||||
===================
|
||||
|
||||
* Bump `opentype.js@0.7.3`
|
||||
|
||||
1.3.7 / 2017-06-11
|
||||
===================
|
||||
|
||||
* Bump `opentype.js@0.7.2`
|
||||
|
||||
1.3.6 / 2017-06-03
|
||||
===================
|
||||
|
||||
* Improve security by randomize svg path command
|
||||
|
||||
1.3.5 / 2017-05-08
|
||||
===================
|
||||
|
||||
* Bump `opentype.js@0.7.1`
|
||||
* Fixed some code style inconsistence
|
||||
21
backend/node_modules/svg-captcha/LICENSE.md
generated
vendored
Normal file
21
backend/node_modules/svg-captcha/LICENSE.md
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 - present Weilin Shi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
123
backend/node_modules/svg-captcha/README.md
generated
vendored
Normal file
123
backend/node_modules/svg-captcha/README.md
generated
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||

|
||||
|
||||
<div align="center">
|
||||
|
||||
[](https://travis-ci.org/lemonce/svg-captcha)
|
||||
[](https://www.npmjs.com/package/svg-captcha)
|
||||
[](https://www.npmjs.com/package/svg-captcha)
|
||||
|
||||
</div>
|
||||
|
||||
> generate svg captcha in node.js
|
||||
|
||||
## Translations
|
||||
[中文](README_CN.md)
|
||||
|
||||
## useful if you
|
||||
|
||||
- cannot or do not want to use google recaptcha
|
||||
- have issue with install c++ addon
|
||||
|
||||
## install
|
||||
```
|
||||
npm install --save svg-captcha
|
||||
```
|
||||
|
||||
## usage
|
||||
```Javascript
|
||||
var svgCaptcha = require('svg-captcha');
|
||||
|
||||
var captcha = svgCaptcha.create();
|
||||
console.log(captcha);
|
||||
// {data: '<svg.../svg>', text: 'abcd'}
|
||||
```
|
||||
with express
|
||||
```Javascript
|
||||
var svgCaptcha = require('svg-captcha');
|
||||
|
||||
app.get('/captcha', function (req, res) {
|
||||
var captcha = svgCaptcha.create();
|
||||
req.session.captcha = captcha.text;
|
||||
|
||||
res.type('svg');
|
||||
res.status(200).send(captcha.data);
|
||||
});
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
#### `svgCaptcha.create(options)`
|
||||
If no option is passed, you will get a random string of four characters and corresponding svg.
|
||||
|
||||
* `size`: 4 // size of random string
|
||||
* `ignoreChars`: '0o1i' // filter out some characters like 0o1i
|
||||
* `noise`: 1 // number of noise lines
|
||||
* `color`: true // characters will have distinct colors instead of grey, true if background option is set
|
||||
* `background`: '#cc9966' // background color of the svg image
|
||||
|
||||
This function returns an object that has the following property:
|
||||
* `data`: string // svg path data
|
||||
* `text`: string // captcha text
|
||||
|
||||
#### `svgCaptcha.createMathExpr(options)`
|
||||
Similar to create api, you have the above options plus 3 additional:
|
||||
* `mathMin`: 1 // the minimum value the math expression can be
|
||||
* `mathMax`: 9 // the maximum value the math expression can be
|
||||
* `mathOperator`: + // The operator to use, `+`, `-` or `+-` (for random `+` or `-`)
|
||||
|
||||
This function returns an object that has the following property:
|
||||
* `data`: string // svg of the math expression
|
||||
* `text`: string // the answer of the math expression
|
||||
|
||||
#### `svgCaptcha.loadFont(url)`
|
||||
Load your own font and override the default font.
|
||||
* `url`: string // path to your font
|
||||
This api is a wrapper around loadFont api of opentype.js.
|
||||
Your may need experiment around various options to make your own font accessible.
|
||||
See the following api.
|
||||
|
||||
#### `svgCaptcha.options`
|
||||
Gain access to global setting object.
|
||||
It is used for create and createMathExpr api as the default options.
|
||||
|
||||
In addition to size, noise, color, and background, you can also set the following property:
|
||||
* `width`: number // width of captcha
|
||||
* `height`: number // height of captcha
|
||||
* `fontSize`: number // captcha text size
|
||||
* `charPreset`: string // random character preset
|
||||
|
||||
#### `svgCaptcha.randomText([size|options])`
|
||||
return a random string.
|
||||
#### `svgCaptcha(text, options)`
|
||||
return a svg captcha based on text provided.
|
||||
|
||||
In pre 1.1.0 version you have to call these two functions,
|
||||
now you can call create() to save some key strokes ;).
|
||||
|
||||
## sample image
|
||||
default captcha image:
|
||||
|
||||

|
||||
|
||||
math expression image with color options:
|
||||
|
||||

|
||||
|
||||
## why use svg?
|
||||
|
||||
It does not require any c++ addon.
|
||||
The result image is smaller than jpeg image.
|
||||
|
||||
> This has to be a joke. /\<text.+\>;.+\<\/text\>/g.test...
|
||||
|
||||
svg captcha uses opentype.js underneath, which means that there is no
|
||||
'<text>1234</text>'.
|
||||
You get
|
||||
'<path fill="#444" d="M104.83 19.74L107.85 19.74L112 33.56L116.13 19.74L119.15 19.74L113.48 36.85...'
|
||||
instead.
|
||||
|
||||
Even though you can write a program that convert svg to png, svg captcha has done its job
|
||||
—— make captcha recognition harder
|
||||
|
||||
## License
|
||||
[MIT](LICENSE.md)
|
||||
109
backend/node_modules/svg-captcha/README_CN.md
generated
vendored
Normal file
109
backend/node_modules/svg-captcha/README_CN.md
generated
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||

|
||||
|
||||
<div align="center">
|
||||
|
||||
[](https://travis-ci.org/lemonce/svg-captcha)
|
||||
[](https://www.npmjs.com/package/svg-captcha)
|
||||
[](https://www.npmjs.com/package/svg-captcha)
|
||||
|
||||
</div>
|
||||
|
||||
> 在node.js中生成svg格式的验证码
|
||||
|
||||
## Translations
|
||||
[English](README.md)
|
||||
|
||||
## 什么情况下使用SVG验证码?
|
||||
|
||||
- 无法使用 google recaptcha
|
||||
- 无法安装 c++ 模块
|
||||
|
||||
## 安装
|
||||
```
|
||||
npm install --save svg-captcha
|
||||
```
|
||||
|
||||
## 使用方法
|
||||
```js
|
||||
var svgCaptcha = require('svg-captcha');
|
||||
|
||||
var c = svgCaptcha.create();
|
||||
console.log(c);
|
||||
// {data: '<svg.../svg>', text: 'abcd'}
|
||||
```
|
||||
在 express中使用
|
||||
```Javascript
|
||||
var svgCaptcha = require('svg-captcha');
|
||||
|
||||
app.get('/captcha', function (req, res) {
|
||||
var captcha = svgCaptcha.create();
|
||||
req.session.captcha = captcha.text;
|
||||
|
||||
res.type('svg');
|
||||
res.status(200).send(captcha.data);
|
||||
});
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
#### `svgCaptcha.create(options)`
|
||||
如果没有任何参数,则生成的 svg 图片有4个字符。
|
||||
|
||||
* `size`: 4 // 验证码长度
|
||||
* `ignoreChars`: '0o1i' // 验证码字符中排除 0o1i
|
||||
* `noise`: 1 // 干扰线条的数量
|
||||
* `color`: true // 验证码的字符是否有颜色,默认没有,如果设定了背景,则默认有
|
||||
* `background`: '#cc9966' // 验证码图片背景颜色
|
||||
|
||||
该函数返回的对象拥有以下属性
|
||||
* `data`: string // svg 路径
|
||||
* `text`: string // 验证码文字
|
||||
|
||||
#### `svgCaptcha.createMathExpr(options)`
|
||||
和前面的 api 的参数和返回值都一样。不同的是这个 api 生成的 svg 是一个算数式,而
|
||||
text 属性上是算数式的结果。不过用法和之前是完全一样的。
|
||||
|
||||
#### `svgCaptcha.loadFont(url)`
|
||||
加载字体,覆盖内置的字体。
|
||||
* `url`: string // 字体文件存放路径
|
||||
该接口会调用opentype.js同名的接口。
|
||||
你可能需要更改一些配置才能让你得字体好看。
|
||||
详见下面的这个接口:
|
||||
|
||||
#### `svgCaptcha.options`
|
||||
这是全局配置对象。
|
||||
create和createMathExpr接口的默认配置就是使用的这个对象。
|
||||
|
||||
除了 size, noise, color, 和 background 之外,你还可以修改以下属性:
|
||||
* `width`: number // width of captcha
|
||||
* `height`: number // height of captcha
|
||||
* `fontSize`: number // captcha text size
|
||||
* `charPreset`: string // random character preset
|
||||
|
||||
#### `svgCaptcha.randomText([size|options])`
|
||||
返回随机字符串
|
||||
#### `svgCaptcha(text, options)`
|
||||
返回基于text参数生成得svg路径
|
||||
在 1.1.0 版本之前你需要调用上面的两个接口,但是现在只需要调用 create()
|
||||
一个接口就行,可以少打几个字了 (^_^)/
|
||||
|
||||
## 图片示例
|
||||
默认生成图片:
|
||||
|
||||

|
||||
|
||||
生成数学公式并且有颜色的验证码:
|
||||
|
||||

|
||||
|
||||
## 为什么使用 svg 格式?
|
||||
|
||||
不需要引用 c++ 模块。
|
||||
如果你认为可以用正则匹配text标签,那就大错特错了。
|
||||
这个项目使用了opentype.js,把文字转化为了路径。
|
||||
换句话说,你得到的是
|
||||
'<path fill="#444" d="M104.83 19.74L107.85 19.74L112 33.56L116.13 19.74L119.15 19.74L113.48 36.85...'
|
||||
这样的路径,没有text标签。所以SVG验证码可能比的图片普通验证码要更难识别,因为你必须先做SVG到其它格式的转化。
|
||||
|
||||
## License
|
||||
[MIT](LICENSE.md)
|
||||
1
backend/node_modules/svg-captcha/code-of-conduct.md
generated
vendored
Normal file
1
backend/node_modules/svg-captcha/code-of-conduct.md
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[https://contributor-covenant.org/version/1/4/](https://contributor-covenant.org/version/1/4/)
|
||||
BIN
backend/node_modules/svg-captcha/fonts/Comismsh.ttf
generated
vendored
Normal file
BIN
backend/node_modules/svg-captcha/fonts/Comismsh.ttf
generated
vendored
Normal file
Binary file not shown.
2
backend/node_modules/svg-captcha/fonts/LICENSE.md
generated
vendored
Normal file
2
backend/node_modules/svg-captcha/fonts/LICENSE.md
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
license: free
|
||||
website: http://www.moorstation.org/typoasis/designers/gemnew/home.htm
|
||||
118
backend/node_modules/svg-captcha/index.d.ts
generated
vendored
Normal file
118
backend/node_modules/svg-captcha/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* config captcha generation options
|
||||
*/
|
||||
declare class ConfigObject {
|
||||
/**
|
||||
* default: true
|
||||
* The length of the random string
|
||||
*/
|
||||
size?: number;
|
||||
/**
|
||||
* width of captcha
|
||||
*/
|
||||
width?: number;
|
||||
/**
|
||||
* height of captcha
|
||||
*/
|
||||
height?: number;
|
||||
/**
|
||||
* captcha text size
|
||||
*/
|
||||
fontSize?: number;
|
||||
/**
|
||||
* random character preset
|
||||
*/
|
||||
charPreset?: string;
|
||||
/**
|
||||
* default: false
|
||||
* if false, captcha will be black and white
|
||||
* otherwise, it will be randomly colorized
|
||||
*/
|
||||
color?: boolean;
|
||||
/**
|
||||
* default: false
|
||||
* if set to true, it will draw with light grey color
|
||||
* use if you have a site with dark theme
|
||||
* only active when color is set to false
|
||||
*/
|
||||
inverse?: boolean;
|
||||
/**
|
||||
* default: ''
|
||||
* filter out some characters
|
||||
*/
|
||||
ignoreChars?: string;
|
||||
/**
|
||||
* default: 1
|
||||
* number of noise lines
|
||||
*/
|
||||
noise?: number;
|
||||
/**
|
||||
* default: white
|
||||
* background color of svg image
|
||||
*/
|
||||
background?: string;
|
||||
/**
|
||||
* default: +
|
||||
* the math operator to use, "+", "-" or "+/-"
|
||||
* if unknown operator passed defaults to "+/-"
|
||||
*/
|
||||
mathOperator?: string;
|
||||
/**
|
||||
* default: 1
|
||||
* min value of the math expression
|
||||
*/
|
||||
mathMin?: number;
|
||||
/**
|
||||
* default: 9
|
||||
* max value of the math expression
|
||||
*/
|
||||
mathMax?: number;
|
||||
}
|
||||
/**
|
||||
* result of captcha generation
|
||||
*/
|
||||
interface CaptchaObj {
|
||||
/**
|
||||
* the captcha text,
|
||||
* store this in your session
|
||||
*/
|
||||
text: string,
|
||||
/**
|
||||
* the svg image in string,
|
||||
* set type of image/svg before send to client side
|
||||
*/
|
||||
data: string
|
||||
}
|
||||
/**
|
||||
* This method returns a object that has two props:
|
||||
* data: svg image string
|
||||
* text: captcha text
|
||||
* @param {ConfigObject} [options]
|
||||
* @return {CaptchaObj}
|
||||
*/
|
||||
export function create(options?: ConfigObject): CaptchaObj;
|
||||
/**
|
||||
* This method returns a object that has two props:
|
||||
* data: svg image string
|
||||
* text: captcha text
|
||||
* note that this method generate a math expression
|
||||
* this means that text is the result of the math expression
|
||||
* @param {ConfigObject} [options]
|
||||
* @return {CaptchaObj}
|
||||
*/
|
||||
export function createMathExpr(options?: ConfigObject): CaptchaObj;
|
||||
/**
|
||||
* Override the default font with your own
|
||||
* @param {string} url
|
||||
*/
|
||||
export function loadFont(url: string): void;
|
||||
/**
|
||||
* captcha generation global setting
|
||||
*/
|
||||
export const options: ConfigObject;
|
||||
/**
|
||||
* return a random string
|
||||
* @param {number} size
|
||||
* @return {string}
|
||||
*/
|
||||
export function randomText(size: number): string;
|
||||
1
backend/node_modules/svg-captcha/index.js
generated
vendored
Normal file
1
backend/node_modules/svg-captcha/index.js
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require('./lib');
|
||||
46
backend/node_modules/svg-captcha/lib/ch-to-path.js
generated
vendored
Normal file
46
backend/node_modules/svg-captcha/lib/ch-to-path.js
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
'use strict';
|
||||
const assert = require('assert');
|
||||
|
||||
function rndPathCmd(cmd) {
|
||||
const r = (Math.random() * 0.2) - 0.1;
|
||||
|
||||
switch (cmd.type) {
|
||||
case 'M': case 'L':
|
||||
cmd.x += r;
|
||||
cmd.y += r;
|
||||
break;
|
||||
case 'Q': case 'C':
|
||||
cmd.x += r;
|
||||
cmd.y += r;
|
||||
cmd.x1 += r;
|
||||
cmd.y1 += r;
|
||||
break;
|
||||
default:
|
||||
// Close path cmd
|
||||
break;
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
module.exports = function (text, opts) {
|
||||
const ch = text[0];
|
||||
assert(ch, 'expect a string');
|
||||
|
||||
const fontSize = opts.fontSize;
|
||||
const fontScale = fontSize / opts.font.unitsPerEm;
|
||||
|
||||
const glyph = opts.font.charToGlyph(ch);
|
||||
const width = glyph.advanceWidth ? glyph.advanceWidth * fontScale : 0;
|
||||
const left = opts.x - (width / 2);
|
||||
|
||||
const height = (opts.ascender + opts.descender) * fontScale;
|
||||
const top = opts.y + (height / 2);
|
||||
const path = glyph.getPath(left, top, fontSize);
|
||||
// Randomize path commands
|
||||
path.commands.forEach(rndPathCmd);
|
||||
|
||||
const pathData = path.toPathData();
|
||||
|
||||
return pathData;
|
||||
};
|
||||
3
backend/node_modules/svg-captcha/lib/char-preset.js
generated
vendored
Normal file
3
backend/node_modules/svg-captcha/lib/char-preset.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
91
backend/node_modules/svg-captcha/lib/index.js
generated
vendored
Normal file
91
backend/node_modules/svg-captcha/lib/index.js
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
'use strict';
|
||||
const chToPath = require('./ch-to-path');
|
||||
const random = require('./random');
|
||||
const optionMngr = require('./option-manager');
|
||||
|
||||
const opts = optionMngr.options;
|
||||
|
||||
const getLineNoise = function (width, height, options) {
|
||||
const hasColor = options.color;
|
||||
const noiseLines = [];
|
||||
const min = options.inverse ? 7 : 1;
|
||||
const max = options.inverse ? 15 : 9;
|
||||
let i = -1;
|
||||
|
||||
while (++i < options.noise) {
|
||||
const start = `${random.int(1, 21)} ${random.int(1, height - 1)}`;
|
||||
const end = `${random.int(width - 21, width - 1)} ${random.int(1, height - 1)}`;
|
||||
const mid1 = `${random.int((width / 2) - 21, (width / 2) + 21)} ${random.int(1, height - 1)}`;
|
||||
const mid2 = `${random.int((width / 2) - 21, (width / 2) + 21)} ${random.int(1, height - 1)}`;
|
||||
const color = hasColor ? random.color() : random.greyColor(min, max);
|
||||
noiseLines.push(`<path d="M${start} C${mid1},${mid2},${end}" stroke="${color}" fill="none"/>`);
|
||||
}
|
||||
|
||||
return noiseLines;
|
||||
};
|
||||
|
||||
const getText = function (text, width, height, options) {
|
||||
const len = text.length;
|
||||
const spacing = (width - 2) / (len + 1);
|
||||
const min = options.inverse ? 10 : 0;
|
||||
const max = options.inverse ? 14 : 4;
|
||||
let i = -1;
|
||||
const out = [];
|
||||
|
||||
while (++i < len) {
|
||||
const x = spacing * (i + 1);
|
||||
const y = height / 2;
|
||||
const charPath = chToPath(text[i], Object.assign({x, y}, options));
|
||||
|
||||
const color = options.color ?
|
||||
random.color(options.background) : random.greyColor(min, max);
|
||||
out.push(`<path fill="${color}" d="${charPath}"/>`);
|
||||
}
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
const createCaptcha = function (text, options) {
|
||||
text = text || random.captchaText();
|
||||
options = Object.assign({}, opts, options);
|
||||
const width = options.width;
|
||||
const height = options.height;
|
||||
const bg = options.background;
|
||||
if (bg) {
|
||||
options.color = true;
|
||||
}
|
||||
|
||||
const bgRect = bg ?
|
||||
`<rect width="100%" height="100%" fill="${bg}"/>` : '';
|
||||
const paths =
|
||||
[].concat(getLineNoise(width, height, options))
|
||||
.concat(getText(text, width, height, options))
|
||||
.sort(() => Math.random() - 0.5)
|
||||
.join('');
|
||||
const start = `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0,0,${width},${height}">`;
|
||||
const xml = `${start}${bgRect}${paths}</svg>`;
|
||||
|
||||
return xml;
|
||||
};
|
||||
|
||||
const create = function (options) {
|
||||
const text = random.captchaText(options);
|
||||
const data = createCaptcha(text, options);
|
||||
|
||||
return {text, data};
|
||||
};
|
||||
|
||||
const createMathExpr = function (options) {
|
||||
const expr = random.mathExpr(options.mathMin, options.mathMax, options.mathOperator);
|
||||
const text = expr.text;
|
||||
const data = createCaptcha(expr.equation, options);
|
||||
|
||||
return {text, data};
|
||||
};
|
||||
|
||||
module.exports = createCaptcha;
|
||||
module.exports.randomText = random.captchaText;
|
||||
module.exports.create = create;
|
||||
module.exports.createMathExpr = createMathExpr;
|
||||
module.exports.options = opts;
|
||||
module.exports.loadFont = optionMngr.loadFont;
|
||||
32
backend/node_modules/svg-captcha/lib/option-manager.js
generated
vendored
Normal file
32
backend/node_modules/svg-captcha/lib/option-manager.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
'use strict';
|
||||
const path = require('path');
|
||||
const opentype = require('opentype.js');
|
||||
const charPreset = require('./char-preset');
|
||||
|
||||
const fontPath = path.join(__dirname, '../fonts/Comismsh.ttf');
|
||||
const font = opentype.loadSync(fontPath);
|
||||
const ascender = font.ascender;
|
||||
const descender = font.descender;
|
||||
|
||||
const options = {
|
||||
width: 150,
|
||||
height: 50,
|
||||
noise: 1,
|
||||
color: false,
|
||||
background: '',
|
||||
size: 4,
|
||||
ignoreChars: '',
|
||||
fontSize: 56,
|
||||
charPreset, font, ascender, descender
|
||||
};
|
||||
|
||||
const loadFont = filepath => {
|
||||
const font = opentype.loadSync(filepath);
|
||||
options.font = font;
|
||||
options.ascender = font.ascender;
|
||||
options.descender = font.descender;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
options, loadFont
|
||||
};
|
||||
148
backend/node_modules/svg-captcha/lib/random.js
generated
vendored
Normal file
148
backend/node_modules/svg-captcha/lib/random.js
generated
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
'use strict';
|
||||
const opts = require('./option-manager').options;
|
||||
|
||||
const randomInt = function (min, max) {
|
||||
return Math.round(min + (Math.random() * (max - min)));
|
||||
};
|
||||
|
||||
const stripCharsFromString = function (string, chars) {
|
||||
return string.split('').filter(char => chars.indexOf(char) === -1);
|
||||
};
|
||||
|
||||
exports.int = randomInt;
|
||||
|
||||
exports.greyColor = function (min, max) {
|
||||
min = min || 1;
|
||||
max = max || 9;
|
||||
const int = randomInt(min, max).toString(16);
|
||||
|
||||
return `#${int}${int}${int}`;
|
||||
};
|
||||
|
||||
exports.captchaText = function (options) {
|
||||
if (typeof options === 'number') {
|
||||
options = {size: options};
|
||||
}
|
||||
options = options || {};
|
||||
|
||||
const size = options.size || 4;
|
||||
const ignoreChars = options.ignoreChars || '';
|
||||
let i = -1;
|
||||
let out = '';
|
||||
let chars = options.charPreset || opts.charPreset;
|
||||
|
||||
if (ignoreChars) {
|
||||
chars = stripCharsFromString(chars, ignoreChars);
|
||||
}
|
||||
|
||||
const len = chars.length - 1;
|
||||
|
||||
while (++i < size) {
|
||||
out += chars[randomInt(0, len)];
|
||||
}
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
const mathExprPlus = function(leftNumber, rightNumber){
|
||||
const text = (leftNumber + rightNumber).toString();
|
||||
const equation = leftNumber + '+' + rightNumber;
|
||||
return {text, equation}
|
||||
}
|
||||
|
||||
const mathExprMinus = function(leftNumber, rightNumber){
|
||||
const text = (leftNumber - rightNumber).toString();
|
||||
const equation = leftNumber + '-' + rightNumber;
|
||||
return {text, equation}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a simple math expression using either the + or - operator
|
||||
* @param {number} [min] - The min value of the math expression defaults to 1
|
||||
* @param {number} [max] - The max value of the math expression defaults to 9
|
||||
* @param {string} [operator] - The operator(s) to use
|
||||
* @returns {{equation: string, text: string}}
|
||||
*/
|
||||
exports.mathExpr = function (min, max, operator) {
|
||||
min = min || 1;
|
||||
max = max || 9;
|
||||
operator = operator || '+';
|
||||
const left = randomInt(min, max);
|
||||
const right = randomInt(min, max);
|
||||
switch(operator){
|
||||
case '+':
|
||||
return mathExprPlus(left, right)
|
||||
case '-':
|
||||
return mathExprMinus(left, right)
|
||||
default:
|
||||
return (randomInt(1, 2) % 2) ? mathExprPlus(left, right) : mathExprMinus(left, right);
|
||||
}
|
||||
};
|
||||
|
||||
// https://github.com/jquery/jquery-color/blob/master/jquery.color.js#L432
|
||||
// The idea here is generate color in hsl first and convert that to rgb color
|
||||
exports.color = function (bgColor) {
|
||||
// Random 24 colors
|
||||
// or based on step
|
||||
const hue = randomInt(0, 24) / 24;
|
||||
|
||||
const saturation = randomInt(60, 80) / 100;
|
||||
const bgLightness = bgColor ? getLightness(bgColor) : 1.0;
|
||||
let minLightness;
|
||||
let maxLightness;
|
||||
if (bgLightness >= 0.5) {
|
||||
minLightness = Math.round(bgLightness * 100) - 45;
|
||||
maxLightness = Math.round(bgLightness * 100) - 25;
|
||||
} else {
|
||||
minLightness = Math.round(bgLightness * 100) + 25;
|
||||
maxLightness = Math.round(bgLightness * 100) + 45;
|
||||
}
|
||||
const lightness = randomInt(minLightness, maxLightness) / 100;
|
||||
|
||||
const q = lightness < 0.5 ?
|
||||
lightness * (lightness + saturation) :
|
||||
lightness + saturation - (lightness * saturation);
|
||||
const p = (2 * lightness) - q;
|
||||
|
||||
const r = Math.floor(hue2rgb(p, q, hue + (1 / 3)) * 255);
|
||||
const g = Math.floor(hue2rgb(p, q, hue) * 255);
|
||||
const b = Math.floor(hue2rgb(p, q, hue - (1 / 3)) * 255);
|
||||
/* eslint-disable no-mixed-operators */
|
||||
const c = ((b | g << 8 | r << 16) | 1 << 24).toString(16).slice(1);
|
||||
|
||||
return '#' + c;
|
||||
};
|
||||
|
||||
function getLightness(rgbColor) {
|
||||
if (rgbColor[0] !== '#') {
|
||||
return 1.0; // Invalid color ?
|
||||
}
|
||||
rgbColor = rgbColor.slice(1);
|
||||
if (rgbColor.length === 3) {
|
||||
rgbColor = rgbColor[0] + rgbColor[0] +
|
||||
rgbColor[1] + rgbColor[1] + rgbColor[2] + rgbColor[2];
|
||||
}
|
||||
|
||||
const hexColor = parseInt(rgbColor, 16);
|
||||
const r = hexColor >> 16;
|
||||
const g = hexColor >> 8 & 255;
|
||||
const b = hexColor & 255;
|
||||
const max = Math.max(r, g, b);
|
||||
const min = Math.min(r, g, b);
|
||||
|
||||
return (max + min) / (2 * 255);
|
||||
}
|
||||
|
||||
function hue2rgb(p, q, h) {
|
||||
h = (h + 1) % 1;
|
||||
if (h * 6 < 1) {
|
||||
return p + (q - p) * h * 6;
|
||||
}
|
||||
if (h * 2 < 1) {
|
||||
return q;
|
||||
}
|
||||
if (h * 3 < 2) {
|
||||
return p + (q - p) * ((2 / 3) - h) * 6;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
59
backend/node_modules/svg-captcha/package.json
generated
vendored
Normal file
59
backend/node_modules/svg-captcha/package.json
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"name": "svg-captcha",
|
||||
"version": "1.4.0",
|
||||
"description": "generate svg captcha in node.js or express.js",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
"lint": "xo"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/steambap/svg-captcha.git"
|
||||
},
|
||||
"keywords": [
|
||||
"captcha",
|
||||
"svg",
|
||||
"node captcha",
|
||||
"captcha generator",
|
||||
"captcha alternative"
|
||||
],
|
||||
"author": {
|
||||
"name": "Weilin Shi",
|
||||
"email": "934587911@qq.com"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.x"
|
||||
},
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/steambap/svg-captcha/issues"
|
||||
},
|
||||
"homepage": "https://github.com/steambap/svg-captcha#readme",
|
||||
"dependencies": {
|
||||
"opentype.js": "^0.7.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jest": "^21.1.0",
|
||||
"jest-environment-node-debug": "^2.0.0",
|
||||
"xo": "^0.18.2"
|
||||
},
|
||||
"xo": {
|
||||
"esnext": true,
|
||||
"envs": [
|
||||
"jest"
|
||||
],
|
||||
"rules": {
|
||||
"linebreak-style": [
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
"typings": "index.d.ts",
|
||||
"files": [
|
||||
"fonts/*",
|
||||
"lib/*",
|
||||
"index.d.ts",
|
||||
"*.md"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user