71 lines
2.3 KiB
JavaScript
71 lines
2.3 KiB
JavaScript
#!/bin/bash
|
|
# Minimal JWT/OAuth2 server for Ditto
|
|
# Serves a JWKS endpoint and validates tokens signed with DITTO_JWT_SECRET
|
|
|
|
cat > /tmp/oauth2-server.js << 'EOF'
|
|
const http = require('http');
|
|
const crypto = require('crypto');
|
|
|
|
const SECRET = process.env.DITTO_JWT_SECRET || 'my-ditto-jwt-secret-key-12345';
|
|
const PORT = 3000;
|
|
|
|
function base64url(buf) {
|
|
return buf.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
|
|
}
|
|
|
|
// Generate a token
|
|
function generateToken(sub, scope) {
|
|
const header = { alg: 'RS256', typ: 'JWT', kid: 'ditto-local' };
|
|
const now = Math.floor(Date.now() / 1000);
|
|
const payload = {
|
|
iss: 'http://localhost:' + PORT,
|
|
sub: sub,
|
|
aud: 'ditto:cognito',
|
|
iat: now,
|
|
exp: now + 3600,
|
|
scope: scope
|
|
};
|
|
const h = base64url(Buffer.from(JSON.stringify(header)));
|
|
const p = base64url(Buffer.from(JSON.stringify(payload)));
|
|
const sig = base64url(
|
|
crypto.createHmac('sha256', SECRET).update(h + '.' + p).digest()
|
|
);
|
|
return h + '.' + p + '.' + sig;
|
|
}
|
|
|
|
const server = http.createServer((req, res) => {
|
|
res.setHeader('Content-Type', 'application/json');
|
|
|
|
if (req.url === '/.well-known/openid-configuration') {
|
|
res.end(JSON.stringify({
|
|
issuer: 'http://localhost:' + PORT,
|
|
jwks_uri: 'http://localhost:' + PORT + '/.well-known/jwks.json',
|
|
token_endpoint: 'http://localhost:' + PORT + '/token'
|
|
}));
|
|
} else if (req.url === '/.well-known/jwks.json') {
|
|
// Extract public key from secret (for HS256 we just return the secret as k)
|
|
const jwk = {
|
|
kty: 'oct',
|
|
kid: 'ditto-local',
|
|
use: 'sig',
|
|
alg: 'HS256',
|
|
k: base64url(Buffer.from(SECRET))
|
|
};
|
|
res.end(JSON.stringify({ keys: [jwk] }));
|
|
} else if (req.url === '/token') {
|
|
const token = generateToken('ditto', 'READ_WRITE');
|
|
res.end(JSON.stringify({ access_token: token, token_type: 'Bearer', expires_in: 3600 }));
|
|
} else {
|
|
res.statusCode = 404;
|
|
res.end('{}');
|
|
}
|
|
});
|
|
|
|
server.listen(PORT, '0.0.0.0', () => {
|
|
console.log('OAuth2 server listening on port ' + PORT);
|
|
console.log('Token: ' + generateToken('ditto', scope='READ_WRITE'));
|
|
});
|
|
EOF
|
|
|
|
node /tmp/oauth2-server.js
|