
Security News
Axios Maintainer Confirms Social Engineering Attack Behind npm Compromise
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.
@berlinsms/plain-js-captcha
Advanced tools
A time consuming captcha component for Plain JavaScript (no framework required)
Eine Captcha-Lösung in reinem JavaScript - ohne React oder andere Frameworks.
npm install @berlinsms/plain-js-captcha
<!-- CSS -->
<link rel="stylesheet" href="https://unpkg.com/@berlinsms/plain-js-captcha/dist/bsms-captcha.css">
<!-- JavaScript -->
<script src="https://unpkg.com/@berlinsms/plain-js-captcha/dist/bsms-captcha.js"></script>
Lade die Dateien aus dem dist/ Ordner herunter:
bsms-captcha.jsbsms-captcha.cssEinfachste Methode - Keine manuelle Initialisierung nötig!
<!DOCTYPE html>
<html>
<head>
<!-- CSS -->
<link rel="stylesheet" href="https://unpkg.com/@berlinsms/plain-js-captcha/dist/bsms-captcha.css">
</head>
<body>
<!-- JavaScript -->
<script src="https://unpkg.com/@berlinsms/plain-js-captcha/dist/bsms-captcha.js"></script>
</body>
</html>
<form id="myForm">
<input type="text" name="username" required>
<input type="email" name="email" required>
<!-- Captcha wird AUTOMATISCH initialisiert! -->
<div class="bsms-captcha-container"
data-sitekey="YOUR-SITEKEY"
data-callback="onCaptchaComplete"
data-error-callback="onCaptchaError"
data-expired-callback="onCaptchaExpired">
</div>
<button type="submit">Absenden</button>
</form>
// Globale Callback-Funktionen
function onCaptchaComplete(token) {
console.log('Captcha abgeschlossen! Token:', token);
// Formular-Submit erlauben
}
function onCaptchaError(error) {
console.error('Captcha Fehler:', error);
}
function onCaptchaExpired() {
console.log('Captcha abgelaufen');
}
Fertig! 🎉 Das Captcha wird automatisch beim Laden der Seite initialisiert.
Falls du mehr Kontrolle brauchst:
var captcha = new BSMSCaptcha({
sitekey: 'YOUR-SITEKEY',
container: document.getElementById('captcha-container'),
form: document.getElementById('myForm'),
start: 'auto', // oder 'click'
onComplete: function(token) {
console.log('Captcha completed!', token);
},
onError: function(error) {
console.error('Error:', error);
},
onExpire: function() {
console.log('Expired');
}
});
});
import '@berlinsms/plain-js-captcha/dist/bsms-captcha.css';
// BSMSCaptcha ist global verfügbar
const captcha = new BSMSCaptcha({ /* ... */ });
require('@berlinsms/plain-js-captcha/dist/bsms-captcha.css');
const BSMSCaptcha = require('@berlinsms/plain-js-captcha');
import { useEffect, useRef } from 'react';
import '@berlinsms/plain-js-captcha/dist/bsms-captcha.css';
function MyForm() {
const captchaRef = useRef(null);
const containerRef = useRef(null);
useEffect(() => {
if (containerRef.current) {
captchaRef.current = new BSMSCaptcha({
sitekey: 'YOUR-SITEKEY',
container: containerRef.current,
onComplete: (token) => console.log('Done!', token)
});
}
return () => {
if (captchaRef.current) captchaRef.current.destroy();
};
}, []);
return <div ref={containerRef}></div>;
}
| Attribut | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
data-sitekey | string | ✅ Ja | Ihr BerlinSMS Sitekey |
data-callback | string | ❌ Nein | Name der globalen Callback-Funktion (onComplete) |
data-error-callback | string | ❌ Nein | Name der globalen Error-Callback-Funktion |
data-expired-callback | string | ❌ Nein | Name der globalen Expire-Callback-Funktion |
data-start | string | ❌ Nein | 'auto' (Standard) oder 'click' |
| Option | Typ | Standard | Beschreibung |
|---|---|---|---|
sitekey | string | erforderlich | Ihr BerlinSMS Sitekey |
container | HTMLElement | erforderlich | Container-Element für das Captcha |
form | HTMLFormElement | null | Formular, in das Hidden-Inputs eingefügt werden |
start | string | 'auto' | 'auto' oder 'click' |
className | string | 'captcha' | Zusätzliche CSS-Klasse |
onComplete | function | - | Callback bei erfolgreicher Validierung |
onError | function | - | Callback bei Fehler |
onExpire | function | - | Callback bei Ablauf |
Das Script stellt eine globale bsmsCaptcha API zur Verfügung:
bsmsCaptcha.reset(containerId)Setzt ein Captcha zurück.
bsmsCaptcha.reset('myCaptcha');
// oder mit Element-Referenz
bsmsCaptcha.reset(document.getElementById('myCaptcha'));
bsmsCaptcha.getResponse(containerId)Holt den Token aus einem Captcha.
var token = bsmsCaptcha.getResponse('myCaptcha');
console.log(token);
bsmsCaptcha.render(containerId, options)Manuelles Rendern eines Captchas.
bsmsCaptcha.render('myCaptcha', {
sitekey: 'YOUR-SITEKEY',
start: 'auto'
});
bsmsCaptcha.renderAll()Re-rendert alle Captchas auf der Seite.
bsmsCaptcha.renderAll();
Nach erfolgreicher Captcha-Validierung werden automatisch folgende Hidden-Inputs in das Formular eingefügt:
<input type="hidden" name="bsms-captcha-token" id="bsms-captcha-token" value="...">
<input type="hidden" name="bsms-captcha-code" id="bsms-captcha-code" value="...">
Diese Werte werden beim Formular-Submit automatisch mitgesendet.
captcha.reset()Setzt das Captcha zurück in den Ausgangszustand.
captcha.reset();
captcha.destroy()Entfernt das Captcha vollständig und bereinigt alle Ressourcen.
captcha.destroy();
start: 'auto')Das Captcha startet automatisch nach dem Laden:
var captcha = new BSMSCaptcha({
sitekey: 'YOUR-SITEKEY',
container: document.getElementById('captcha-container'),
start: 'auto'
});
start: 'click')Das Captcha muss vom Benutzer manuell gestartet werden:
var captcha = new BSMSCaptcha({
sitekey: 'YOUR-SITEKEY',
container: document.getElementById('captcha-container'),
start: 'click'
});
Nach dem Absenden des Formulars müssen Sie das Captcha-Token auf Ihrem Server validieren:
// Beispiel für Node.js/Express
app.post('/submit', async (req, res) => {
const token = req.body['bsms-captcha-token'];
// Token an BerlinSMS API senden zur Validierung
const response = await fetch('https://api.berlinsms.de/captcha/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
token: token,
sitekey: 'YOUR-SITEKEY'
})
});
const result = await response.json();
if (result.success) {
// Captcha ist gültig
// Formular verarbeiten...
} else {
// Captcha ist ungültig
res.status(400).send('Captcha validation failed');
}
});
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Captcha Beispiel</title>
<link rel="stylesheet" href="bsms-captcha.css">
</head>
<body>
<form id="contactForm">
<div>
<label>Name:</label>
<input type="text" name="name" required>
</div>
<div>
<label>E-Mail:</label>
<input type="email" name="email" required>
</div>
<div>
<label>Nachricht:</label>
<textarea name="message" required></textarea>
</div>
<!-- Captcha -->
<div id="captcha-widget"></div>
<button type="submit" id="submitBtn" disabled>Senden</button>
</form>
<script src="bsms-captcha.js"></script>
<script>
var form = document.getElementById('contactForm');
var submitBtn = document.getElementById('submitBtn');
// Captcha initialisieren
var captcha = new BSMSCaptcha({
sitekey: 'demo-sitekey-12345',
container: document.getElementById('captcha-widget'),
form: form,
start: 'auto',
onComplete: function(token) {
// Submit-Button aktivieren
submitBtn.disabled = false;
console.log('Captcha completed:', token);
},
onError: function(error) {
// Submit-Button deaktivieren
submitBtn.disabled = true;
alert('Captcha Fehler: ' + error);
},
onExpire: function() {
// Submit-Button deaktivieren
submitBtn.disabled = true;
alert('Captcha ist abgelaufen. Bitte erneut durchführen.');
}
});
// Formular-Submit
form.addEventListener('submit', function(e) {
e.preventDefault();
var token = document.getElementById('bsms-captcha-token');
if (!token || !token.value) {
alert('Bitte Captcha vervollständigen!');
return;
}
// Formular-Daten senden
var formData = new FormData(form);
fetch('/submit', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
alert('Formular erfolgreich gesendet!');
form.reset();
captcha.reset();
})
.catch(error => {
alert('Fehler beim Senden: ' + error);
});
});
</script>
</body>
</html>
Das Captcha kann über CSS-Variablen angepasst werden:
:root {
--bmstwofa-c-brand1: #A13535; /* Primärfarbe */
--bmstwofa-c-brand2: #327E8B; /* Sekundärfarbe */
--bmstwofa-c-error: #d50303; /* Fehlerfarbe */
--bmstwofa-c-success: darkgreen; /* Erfolgsfarbe */
}
Oder eigene CSS-Klassen hinzufügen:
var captcha = new BSMSCaptcha({
sitekey: 'YOUR-SITEKEY',
container: document.getElementById('captcha-container'),
className: 'custom-captcha'
});
.custom-captcha {
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
MIT License - siehe plain-js-captcha/package.json
BerlinSMS
Bei Problemen oder Fragen: support@berlinsms.de
FAQs
A time consuming captcha component for Plain JavaScript (no framework required)
We found that @berlinsms/plain-js-captcha demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.