mirror of
https://github.com/mCaptcha/glue.git
synced 2026-01-24 23:16:49 +00:00
@mcaptcha/react-glue implementation
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
browser: true,
|
||||
es2021: true,
|
||||
},
|
||||
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
|
||||
parser: "@typescript-eslint/parser",
|
||||
|
||||
@@ -6,10 +6,12 @@
|
||||
"private": true,
|
||||
"workspaces": {
|
||||
"packages": [
|
||||
"packages/vanilla"
|
||||
"packages/vanilla",
|
||||
"packages/react-glue"
|
||||
],
|
||||
"nohoist": [
|
||||
"packages/*"
|
||||
"packages/vanilla",
|
||||
"packages/react-glue"
|
||||
]
|
||||
},
|
||||
"license": "(MIT OR Apache-2.0)",
|
||||
|
||||
9
packages/react-glue/.editorconfig
Normal file
9
packages/react-glue/.editorconfig
Normal file
@@ -0,0 +1,9 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
5
packages/react-glue/.eslintignore
Normal file
5
packages/react-glue/.eslintignore
Normal file
@@ -0,0 +1,5 @@
|
||||
build/
|
||||
dist/
|
||||
node_modules/
|
||||
.snapshots/
|
||||
*.min.js
|
||||
47
packages/react-glue/.eslintrc
Normal file
47
packages/react-glue/.eslintrc
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"extends": [
|
||||
"standard",
|
||||
"standard-react",
|
||||
"plugin:prettier/recommended",
|
||||
"prettier/standard",
|
||||
"prettier/react",
|
||||
"plugin:@typescript-eslint/eslint-recommended"
|
||||
],
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2020,
|
||||
"ecmaFeatures": {
|
||||
"legacyDecorators": true,
|
||||
"jsx": true
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"react": {
|
||||
"version": "16"
|
||||
}
|
||||
},
|
||||
"rules": {
|
||||
"@typescript-eslint/member-delimiter-style": [
|
||||
"error",
|
||||
{
|
||||
"multiline": {
|
||||
"delimiter": 'none',
|
||||
"requireLast": true
|
||||
},
|
||||
"singleline": {
|
||||
"delimiter": 'none',
|
||||
"requireLast": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"space-before-function-paren": 0,
|
||||
"react/prop-types": 0,
|
||||
"react/jsx-handler-names": 0,
|
||||
"react/jsx-fragments": 0,
|
||||
"react/no-unused-prop-types": 0,
|
||||
"import/export": 0
|
||||
}
|
||||
}
|
||||
10
packages/react-glue/.prettierrc
Normal file
10
packages/react-glue/.prettierrc
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"jsxSingleQuote": true,
|
||||
"semi": false,
|
||||
"tabWidth": 2,
|
||||
"bracketSpacing": true,
|
||||
"jsxBracketSameLine": false,
|
||||
"arrowParens": "always",
|
||||
"trailingComma": "none"
|
||||
}
|
||||
4
packages/react-glue/.travis.yml
Normal file
4
packages/react-glue/.travis.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 12
|
||||
- 10
|
||||
30
packages/react-glue/README.md
Normal file
30
packages/react-glue/README.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# react-glue
|
||||
|
||||
> Made with create-react-library
|
||||
|
||||
[](https://www.npmjs.com/package/@mcaptcha/react-glue) [](https://standardjs.com)
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm install --save react-glue
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx
|
||||
import React, { Component } from 'react'
|
||||
|
||||
import MyComponent from 'react-glue'
|
||||
import 'react-glue/dist/index.css'
|
||||
|
||||
class Example extends Component {
|
||||
render() {
|
||||
return <MyComponent siteKey="randomSiteKeyAsDisplayedInAdminPanel" />
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Aravinth Manivannan <realaravinth@batsense.net>](https://github.com/Aravinth Manivannan <realaravinth@batsense.net>)
|
||||
5
packages/react-glue/example/README.md
Normal file
5
packages/react-glue/example/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
This example was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
|
||||
|
||||
It is linked to the react-glue package in the parent directory for development purposes.
|
||||
|
||||
You can run `yarn install` and then `yarn start` to test your package.
|
||||
44
packages/react-glue/example/package.json
Normal file
44
packages/react-glue/example/package.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "react-glue-example",
|
||||
"homepage": ".",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "node ../node_modules/react-scripts/bin/react-scripts.js start",
|
||||
"build": "node ../node_modules/react-scripts/bin/react-scripts.js build",
|
||||
"test": "node ../node_modules/react-scripts/bin/react-scripts.js test",
|
||||
"eject": "node ../node_modules/react-scripts/bin/react-scripts.js eject"
|
||||
},
|
||||
"dependencies": {
|
||||
"@testing-library/jest-dom": "link:../node_modules/@testing-library/jest-dom",
|
||||
"@testing-library/react": "link:../node_modules/@testing-library/react",
|
||||
"@testing-library/user-event": "link:../node_modules/@testing-library/user-event",
|
||||
"@types/jest": "link:../node_modules/@types/jest",
|
||||
"@types/node": "link:../node_modules/@types/node",
|
||||
"@types/react": "link:../node_modules/@types/react",
|
||||
"@types/react-dom": "link:../node_modules/@types/react-dom",
|
||||
"react": "link:../node_modules/react",
|
||||
"react-dom": "link:../node_modules/react-dom",
|
||||
"react-scripts": "link:../node_modules/react-scripts",
|
||||
"typescript": "link:../node_modules/typescript",
|
||||
"react-glue": "link:.."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-syntax-object-rest-spread": "^7.8.3"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "react-app"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
||||
BIN
packages/react-glue/example/public/favicon.ico
Normal file
BIN
packages/react-glue/example/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
48
packages/react-glue/example/public/index.html
Normal file
48
packages/react-glue/example/public/index.html
Normal file
@@ -0,0 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1, shrink-to-fit=no"
|
||||
/>
|
||||
<meta name="theme-color" content="#000000" />
|
||||
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is added to the
|
||||
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>react-glue</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>
|
||||
You need to enable JavaScript to run this app.
|
||||
</noscript>
|
||||
|
||||
<div id="root"></div>
|
||||
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
15
packages/react-glue/example/public/manifest.json
Normal file
15
packages/react-glue/example/public/manifest.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"short_name": "react-glue",
|
||||
"name": "react-glue",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
9
packages/react-glue/example/src/App.test.tsx
Normal file
9
packages/react-glue/example/src/App.test.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import App from './App'
|
||||
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div')
|
||||
ReactDOM.render(<App />, div)
|
||||
ReactDOM.unmountComponentAtNode(div)
|
||||
})
|
||||
10
packages/react-glue/example/src/App.tsx
Normal file
10
packages/react-glue/example/src/App.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import React from 'react'
|
||||
|
||||
import { MCaptchaWidget } from '@mcaptcha/react-glue'
|
||||
import 'react-glue/dist/index.css'
|
||||
|
||||
const App = () => {
|
||||
return <MCaptchaWidget siteKey='foo' />
|
||||
}
|
||||
|
||||
export default App
|
||||
14
packages/react-glue/example/src/index.css
Normal file
14
packages/react-glue/example/src/index.css
Normal file
@@ -0,0 +1,14 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
||||
7
packages/react-glue/example/src/index.tsx
Normal file
7
packages/react-glue/example/src/index.tsx
Normal file
@@ -0,0 +1,7 @@
|
||||
import './index.css'
|
||||
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import App from './App'
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById('root'))
|
||||
1
packages/react-glue/example/src/react-app-env.d.ts
vendored
Normal file
1
packages/react-glue/example/src/react-app-env.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/// <reference types="react-scripts" />
|
||||
5
packages/react-glue/example/src/setupTests.ts
Normal file
5
packages/react-glue/example/src/setupTests.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
||||
// allows you to do things like:
|
||||
// expect(element).toHaveTextContent(/react/i)
|
||||
// learn more: https://github.com/testing-library/jest-dom
|
||||
import '@testing-library/jest-dom/extend-expect';
|
||||
22
packages/react-glue/example/tsconfig.json
Normal file
22
packages/react-glue/example/tsconfig.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"module": "esnext",
|
||||
"lib": ["dom", "esnext"],
|
||||
"moduleResolution": "node",
|
||||
"jsx": "react",
|
||||
"sourceMap": true,
|
||||
"declaration": true,
|
||||
"esModuleInterop": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
"noImplicitAny": true,
|
||||
"strictNullChecks": true,
|
||||
"suppressImplicitAnyIndexErrors": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "build"]
|
||||
}
|
||||
96
packages/react-glue/package.json
Normal file
96
packages/react-glue/package.json
Normal file
@@ -0,0 +1,96 @@
|
||||
{
|
||||
"name": "@mcaptcha/react-glue",
|
||||
"version": "0.1.0-alpha-1",
|
||||
"description": "glue code to setup mCaptcha on your React website",
|
||||
"author": "Aravinth Manivannan <realaravinth@batsense.net>",
|
||||
"license": "(MIT OR Apache-2.0)",
|
||||
"keywords": [
|
||||
"mCaptcha",
|
||||
"CAPTCHA",
|
||||
"proof of work",
|
||||
"react"
|
||||
],
|
||||
"homepage": "https://mcaptcha.org",
|
||||
"browser": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"bugs": {
|
||||
"url": "https://github.com/mCaptcha/glue/issues",
|
||||
"email": "realaravinth@batsense.net"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "http://mcaptcha.org/donate"
|
||||
},
|
||||
{
|
||||
"type": "liberapay",
|
||||
"url": "https://liberapay.com/mcaptcha"
|
||||
},
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "http://batsense.net/donate"
|
||||
},
|
||||
{
|
||||
"type": "liberapay",
|
||||
"url": "https://liberapay.com/realaravinth"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mCaptcha/glue.git"
|
||||
},
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.modern.js",
|
||||
"source": "src/index.tsx",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "microbundle-crl --no-compress --format modern,cjs",
|
||||
"start": "microbundle-crl watch --no-compress --format modern,cjs",
|
||||
"prepare": "run-s build",
|
||||
"test": "run-s test:unit test:build",
|
||||
"test:build": "run-s build",
|
||||
"test:lint": "eslint src/",
|
||||
"test:unit": "cross-env CI=1 react-scripts test --env=jsdom",
|
||||
"test:watch": "react-scripts test --env=jsdom",
|
||||
"predeploy": "cd example && yarn install && yarn run build",
|
||||
"deploy": "gh-pages -d example/build"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/jest-dom": "^4.2.4",
|
||||
"@testing-library/react": "^9.5.0",
|
||||
"@testing-library/user-event": "^7.2.1",
|
||||
"@types/node": "^12.12.38",
|
||||
"@types/react": "^16.9.27",
|
||||
"@types/react-dom": "^16.9.7",
|
||||
"@typescript-eslint/eslint-plugin": "^2.26.0",
|
||||
"@typescript-eslint/parser": "^2.26.0",
|
||||
"babel-eslint": "^10.0.3",
|
||||
"cross-env": "^7.0.2",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-prettier": "^6.7.0",
|
||||
"eslint-config-standard": "^14.1.0",
|
||||
"eslint-config-standard-react": "^9.2.0",
|
||||
"eslint-plugin-import": "^2.18.2",
|
||||
"eslint-plugin-node": "^11.0.0",
|
||||
"eslint-plugin-prettier": "^3.1.1",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-react": "^7.17.0",
|
||||
"eslint-plugin-standard": "^4.0.1",
|
||||
"gh-pages": "^2.2.0",
|
||||
"microbundle-crl": "^0.13.10",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.0.4",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-scripts": "^3.4.1",
|
||||
"typescript": "^3.7.5"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
5
packages/react-glue/src/.eslintrc
Normal file
5
packages/react-glue/src/.eslintrc
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"env": {
|
||||
"jest": true
|
||||
}
|
||||
}
|
||||
50
packages/react-glue/src/index.test.tsx
Normal file
50
packages/react-glue/src/index.test.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
import React from 'react'
|
||||
import { render, unmountComponentAtNode } from 'react-dom'
|
||||
import { act } from 'react-dom/test-utils'
|
||||
|
||||
import { MCaptchaWidget, Config, INPUT_NAME, ConfigurationError } from '.'
|
||||
|
||||
let container = null
|
||||
beforeEach(() => {
|
||||
// setup a DOM element as a render target
|
||||
container = document.createElement('div')
|
||||
document.body.appendChild(container)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
// cleanup on exiting
|
||||
if (container) {
|
||||
unmountComponentAtNode(container)
|
||||
container.remove()
|
||||
container = null
|
||||
}
|
||||
})
|
||||
|
||||
describe('MCaptchaWidget', () => {
|
||||
it('with site key', () => {
|
||||
if (container) {
|
||||
act(() => render(<MCaptchaWidget siteKey='foo' />, container))
|
||||
let w = container.querySelector(`#${INPUT_NAME}`)
|
||||
expect(w).toBeTruthy()
|
||||
}
|
||||
})
|
||||
|
||||
it('with widget link', () => {
|
||||
if (container) {
|
||||
act(() =>
|
||||
render(<MCaptchaWidget widgetLink='https://example.com' />, container)
|
||||
)
|
||||
let w = container.querySelector(`#${INPUT_NAME}`)
|
||||
expect(w).toBeTruthy()
|
||||
}
|
||||
})
|
||||
it('without configuration params, should error out', () => {
|
||||
if (container) {
|
||||
try {
|
||||
render(<MCaptchaWidget />, container)
|
||||
} catch (e) {
|
||||
expect(e.message).toBe(new ConfigurationError().message)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
100
packages/react-glue/src/index.tsx
Normal file
100
packages/react-glue/src/index.tsx
Normal file
@@ -0,0 +1,100 @@
|
||||
import * as React from 'react'
|
||||
import { useState, useEffect, ReactElement } from 'react'
|
||||
|
||||
/** Configuration for MCaptchaWidget */
|
||||
export type Config = {
|
||||
/** URL of the widget. Use this only when you are using a self-hosted
|
||||
* instance of mCaptcha with a non-standard(unofficial) path(i.e, widgets
|
||||
* are not served from `/widget/?stiekey=uniqueSitekey` */
|
||||
widgetLink?: URL
|
||||
/** site key as given in the admin dashboard. Widget
|
||||
* link will be derived from this.
|
||||
*/
|
||||
siteKey?: string
|
||||
}
|
||||
|
||||
/** configuration error thrown by MCaptchaWidget */
|
||||
export class ConfigurationError extends Error {
|
||||
/** error message */
|
||||
message = 'Provide either widget link or site key to display mCaptcha widget'
|
||||
}
|
||||
|
||||
export const INPUT_NAME = 'mcaptcha__token'
|
||||
/**
|
||||
* @param {URL?}widgetLink: URL of the widget. Use this only when you are using
|
||||
* a self-hosted instance of mCaptcha with a non-standard(unofficial) path(i.e,
|
||||
* widgets are not served from `/widget/?stiekey=uniqueSitekey`
|
||||
* @param {string?}sitekey: site key as given in the admin dashboard. Widget
|
||||
* link will be derived from this.
|
||||
*
|
||||
* @returns {ReactElement}: mCaptcha widget containing an input field, which
|
||||
* will hold the verification token and an iframe containing the widget
|
||||
*
|
||||
* @throws {ConfigurationError}: This error is thrown when neither widget link
|
||||
* nor site key is provided to this compoenent
|
||||
*/
|
||||
export const MCaptchaWidget = ({
|
||||
widgetLink,
|
||||
siteKey
|
||||
}: Config): ReactElement => {
|
||||
const containerStyle = {
|
||||
width: '340px',
|
||||
height: '78px'
|
||||
}
|
||||
|
||||
let iframeSource: URL
|
||||
if (widgetLink) {
|
||||
iframeSource = widgetLink
|
||||
} else if (siteKey) {
|
||||
iframeSource = new URL(
|
||||
`https://demo.mcaptcha.org/widget/?sitekey=${siteKey}`
|
||||
)
|
||||
} else {
|
||||
throw new ConfigurationError()
|
||||
}
|
||||
|
||||
const [token, setToken] = useState('')
|
||||
|
||||
const handle = (e: MessageEvent): void => {
|
||||
if (new URL(e.origin).host !== iframeSource.host) {
|
||||
console.error(
|
||||
`expected message from ${iframeSource.host} but received message from ${e.origin}. Aborting.`
|
||||
)
|
||||
return
|
||||
}
|
||||
console.log(`received message, setting token to ${e.data.token}`)
|
||||
setToken(e.data.token)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('message', handle)
|
||||
const cleanup = (): void => window.removeEventListener('message', handle)
|
||||
return cleanup
|
||||
})
|
||||
|
||||
return (
|
||||
<div style={containerStyle}>
|
||||
<input
|
||||
id={INPUT_NAME}
|
||||
name={INPUT_NAME}
|
||||
value={token}
|
||||
hidden
|
||||
required
|
||||
type='text'
|
||||
/>
|
||||
<iframe
|
||||
title='mCaptcha'
|
||||
src={iframeSource.toString()}
|
||||
role='presentation'
|
||||
name='mcaptcha-widget__iframe'
|
||||
id='mcaptcha-widget__iframe'
|
||||
scrolling='no'
|
||||
sandbox='allow-same-origin allow-scripts'
|
||||
width='304'
|
||||
height='78'
|
||||
frameBorder='0'
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default MCaptchaWidget
|
||||
1
packages/react-glue/src/react-app-env.d.ts
vendored
Normal file
1
packages/react-glue/src/react-app-env.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/// <reference types="react-scripts" />
|
||||
9
packages/react-glue/src/styles.module.css
Normal file
9
packages/react-glue/src/styles.module.css
Normal file
@@ -0,0 +1,9 @@
|
||||
/* add css module styles here (optional) */
|
||||
|
||||
.test {
|
||||
margin: 2em;
|
||||
padding: 0.5em;
|
||||
border: 2px solid #000;
|
||||
font-size: 2em;
|
||||
text-align: center;
|
||||
}
|
||||
17
packages/react-glue/src/typings.d.ts
vendored
Normal file
17
packages/react-glue/src/typings.d.ts
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Default CSS definition for typescript,
|
||||
* will be overridden with file-specific definitions by rollup
|
||||
*/
|
||||
declare module '*.css' {
|
||||
const content: { [className: string]: string };
|
||||
export default content;
|
||||
}
|
||||
|
||||
interface SvgrComponent extends React.StatelessComponent<React.SVGAttributes<SVGElement>> {}
|
||||
|
||||
declare module '*.svg' {
|
||||
const svgUrl: string;
|
||||
const svgComponent: SvgrComponent;
|
||||
export default svgUrl;
|
||||
export { svgComponent as ReactComponent }
|
||||
}
|
||||
39
packages/react-glue/tsconfig.json
Normal file
39
packages/react-glue/tsconfig.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"module": "esnext",
|
||||
"lib": [
|
||||
"dom",
|
||||
"esnext"
|
||||
],
|
||||
"moduleResolution": "node",
|
||||
"jsx": "react",
|
||||
"sourceMap": true,
|
||||
"declaration": true,
|
||||
"esModuleInterop": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
"noImplicitAny": true,
|
||||
"strictNullChecks": true,
|
||||
"suppressImplicitAnyIndexErrors": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"target": "es5",
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"dist",
|
||||
"example"
|
||||
]
|
||||
}
|
||||
6
packages/react-glue/tsconfig.test.json
Normal file
6
packages/react-glue/tsconfig.test.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs"
|
||||
}
|
||||
}
|
||||
127
packages/react-glue/yarn-error.log
Normal file
127
packages/react-glue/yarn-error.log
Normal file
@@ -0,0 +1,127 @@
|
||||
Arguments:
|
||||
/usr/bin/node /usr/bin/yarn test
|
||||
|
||||
PATH:
|
||||
/usr/lib/safe-rm:/home/aravinth/.nix-profile/bin:/nix/var/nix/profiles/default/bin:/usr/lib/safe-rm:/home/aravinth/.nix-profile/bin:/nix/var/nix/profiles/default/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/home/aravinth/.local/bin/:/home/aravinth/.cargo/bin/:/home/aravinth/go/bin/:/home/aravinth/yarn/bin/:/home/aravinth/.gem/ruby/2.7.0/bin:/home/aravinth/.rustup/toolchains/*/bin/:/home/aravinth/workspace/fabric/bin:/home/aravinth/dotfiles/scripts:/home/aravinth/bin/:/home/aravinth/dotfiles/scripts/redis/:/home/aravinth/.fzf/bin:/opt/hub/bin:/usr/lib/jvm/default/bin:/home/aravinth/.local/bin/:/home/aravinth/.cargo/bin/:/home/aravinth/go/bin/:/home/aravinth/yarn/bin/:/home/aravinth/.gem/ruby/2.7.0/bin:/home/aravinth/.rustup/toolchains/*/bin/:/home/aravinth/workspace/fabric/bin:/home/aravinth/dotfiles/scripts:/home/aravinth/bin/:/home/aravinth/dotfiles/scripts/redis/:/opt/hub/bin
|
||||
|
||||
Yarn version:
|
||||
1.22.17
|
||||
|
||||
Node version:
|
||||
17.1.0
|
||||
|
||||
Platform:
|
||||
linux x64
|
||||
|
||||
Trace:
|
||||
SyntaxError: /home/aravinth/code/mCaptcha/glue/packages/react-glue/package.json: Unexpected token / in JSON at position 1301
|
||||
at JSON.parse (<anonymous>)
|
||||
at /usr/lib/node_modules/yarn/lib/cli.js:1625:59
|
||||
at Generator.next (<anonymous>)
|
||||
at step (/usr/lib/node_modules/yarn/lib/cli.js:310:30)
|
||||
at /usr/lib/node_modules/yarn/lib/cli.js:321:13
|
||||
|
||||
npm manifest:
|
||||
{
|
||||
"name": "@mcaptcha/react-glue",
|
||||
"version": "0.1.0-alpha-1",
|
||||
"description": "glue code to setup mCaptcha on your React website",
|
||||
"author": "Aravinth Manivannan <realaravinth@batsense.net>",
|
||||
"license": "(MIT OR Apache-2.0)",
|
||||
"keywords": [
|
||||
"mCaptcha",
|
||||
"CAPTCHA",
|
||||
"proof of work",
|
||||
"react"
|
||||
],
|
||||
"homepage": "https://mcaptcha.org",
|
||||
"browser": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"bugs": {
|
||||
"url": "https://github.com/mCaptcha/glue/issues",
|
||||
"email": "realaravinth@batsense.net"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "http://mcaptcha.org/donate"
|
||||
},
|
||||
{
|
||||
"type": "liberapay",
|
||||
"url": "https://liberapay.com/mcaptcha"
|
||||
},
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "http://batsense.net/donate"
|
||||
},
|
||||
{
|
||||
"type": "liberapay",
|
||||
"url": "https://liberapay.com/realaravinth"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mCaptcha/glue.git"
|
||||
},
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.modern.js",
|
||||
"source": "src/index.tsx",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "microbundle-crl --no-compress --format modern,cjs",
|
||||
"start": "microbundle-crl watch --no-compress --format modern,cjs",
|
||||
"prepare": "run-s build",
|
||||
//"test": "run-s test:unit test:lint test:build",
|
||||
"test": "run-s test:unit test:build",
|
||||
"test:build": "run-s build",
|
||||
"test:lint": "eslint src/",
|
||||
"test:unit": "cross-env CI=1 react-scripts test --env=jsdom",
|
||||
"test:watch": "react-scripts test --env=jsdom",
|
||||
"predeploy": "cd example && yarn install && yarn run build",
|
||||
"deploy": "gh-pages -d example/build"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/jest-dom": "^4.2.4",
|
||||
"@testing-library/react": "^9.5.0",
|
||||
"@testing-library/user-event": "^7.2.1",
|
||||
"@types/node": "^12.12.38",
|
||||
"@types/react": "^16.9.27",
|
||||
"@types/react-dom": "^16.9.7",
|
||||
"@typescript-eslint/eslint-plugin": "^2.26.0",
|
||||
"@typescript-eslint/parser": "^2.26.0",
|
||||
"babel-eslint": "^10.0.3",
|
||||
"cross-env": "^7.0.2",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-prettier": "^6.7.0",
|
||||
"eslint-config-standard": "^14.1.0",
|
||||
"eslint-config-standard-react": "^9.2.0",
|
||||
"eslint-plugin-import": "^2.18.2",
|
||||
"eslint-plugin-node": "^11.0.0",
|
||||
"eslint-plugin-prettier": "^3.1.1",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-react": "^7.17.0",
|
||||
"eslint-plugin-standard": "^4.0.1",
|
||||
"gh-pages": "^2.2.0",
|
||||
"microbundle-crl": "^0.13.10",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.0.4",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-scripts": "^3.4.1",
|
||||
"typescript": "^3.7.5"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
|
||||
yarn manifest:
|
||||
No manifest
|
||||
|
||||
Lockfile:
|
||||
No lockfile
|
||||
Reference in New Issue
Block a user