2018-10-15 07:18:10 +03:00
'use strict' ;
const express = require ( 'express' ) ,
router = express . Router ( ) ,
crypto = require ( 'crypto' ) ,
2018-10-15 21:45:32 +03:00
request = require ( 'request' ) ,
2018-10-15 07:18:10 +03:00
Parser = require ( 'rss-parser' ) ,
2018-10-15 21:45:32 +03:00
parseFavicon = require ( 'parse-favicon' ) . parseFavicon ,
2018-10-15 07:18:10 +03:00
generateRSAKeypair = require ( 'generate-rsa-keypair' ) ;
router . get ( '/convert' , function ( req , res ) {
let db = req . app . get ( 'db' ) ;
console . log ( req . query ) ;
let username = req . query . username ;
let feed = req . query . feed ;
// reject if username is invalid
if ( username . match ( /^[a-zA-Z0-9_]+$/ ) === null ) {
return res . status ( 400 ) . json ( 'Invalid username! Only alphanumerics and underscore (_) allowed.' ) ;
}
// check to see if feed exists
let result = db . prepare ( 'select * from feeds where feed = ? or username = ?' ) . get ( feed , username ) ;
// see if we already have an entry for this feed
if ( result ) {
// return feed
res . status ( 200 ) . json ( result ) ;
}
else if ( feed && username ) {
console . log ( 'VALIDATING' ) ;
// validate the RSS
let parser = new Parser ( ) ;
parser . parseURL ( feed , function ( err , feedData ) {
if ( err ) {
2019-02-22 22:32:07 +02:00
if ( err . message === 'Status code 400' ) {
err . message = ` That doesn't look like a valid RSS feed. Check <a href=" ${ feed } ">the URL you provided</a> in a feed validator. You can <a href="https://validator.w3.org/feed/check.cgi?url= ${ feed } " target="_blank">click here</a> to pop up a test immediately. `
}
2018-10-15 07:18:10 +03:00
res . status ( 400 ) . json ( { err : err . message } ) ;
}
else {
console . log ( feedData . title ) ;
console . log ( 'end!!!!' ) ;
res . status ( 200 ) . json ( feedData ) ;
let displayName = feedData . title ;
2018-11-18 01:54:57 +02:00
let description = feedData . description ;
2018-10-15 07:18:10 +03:00
let account = username ;
// create new user
let db = req . app . get ( 'db' ) ;
let domain = req . app . get ( 'domain' ) ;
// create keypair
var pair = generateRSAKeypair ( ) ;
2018-10-15 21:45:32 +03:00
getImage ( feed , feedData , imageUrl => {
2018-11-18 01:54:57 +02:00
let actorRecord = createActor ( account , domain , pair . public , displayName , imageUrl , description ) ;
2018-10-15 21:45:32 +03:00
let webfingerRecord = createWebfinger ( account , domain ) ;
const apikey = crypto . randomBytes ( 16 ) . toString ( 'hex' ) ;
db . prepare ( 'insert or replace into accounts(name, actor, apikey, pubkey, privkey, webfinger) values(?, ?, ?, ?, ?, ?)' ) . run ( ` ${ account } @ ${ domain } ` , JSON . stringify ( actorRecord ) , apikey , pair . public , pair . private , JSON . stringify ( webfingerRecord ) ) ;
let content = JSON . stringify ( feedData ) ;
db . prepare ( 'insert or replace into feeds(feed, username, content) values(?, ?, ?)' ) . run ( feed , username , content ) ;
} ) ;
2018-10-15 07:18:10 +03:00
}
} ) ;
}
else {
res . status ( 404 ) . json ( { msg : 'unknown error' } ) ;
}
} ) ;
2018-10-15 21:45:32 +03:00
function getImage ( feed , feedData , cb ) {
let imageUrl = null ;
// if image exists set image
if ( feedData . image && feedData . image . url ) {
imageUrl = feedData . image . url ;
return cb ( imageUrl ) ;
}
// otherwise parse the HTML for the favicon
else {
let favUrl = new URL ( feed ) ;
request ( favUrl . origin , ( err , resp , body ) => {
parseFavicon ( body , { baseURI : favUrl . origin } ) . then ( result => {
if ( result && result . length ) {
return cb ( result [ 0 ] . url ) ;
}
else {
return cb ( null ) ;
}
} ) ;
} ) ;
}
}
2018-11-18 01:54:57 +02:00
function createActor ( name , domain , pubkey , displayName , imageUrl , description ) {
2018-10-15 07:18:10 +03:00
displayName = displayName || name ;
let actor = {
'@context' : [
'https://www.w3.org/ns/activitystreams' ,
'https://w3id.org/security/v1'
] ,
'id' : ` https:// ${ domain } /u/ ${ name } ` ,
'type' : 'Person' ,
'preferredUsername' : ` ${ name } ` ,
'inbox' : ` https:// ${ domain } /api/inbox ` ,
2019-03-11 06:02:12 +02:00
'followers' : ` https:// ${ domain } /u/ ${ name } /followers ` ,
2018-10-15 07:18:10 +03:00
'name' : displayName ,
'publicKey' : {
'id' : ` https:// ${ domain } /u/ ${ name } #main-key ` ,
'owner' : ` https:// ${ domain } /u/ ${ name } ` ,
'publicKeyPem' : pubkey
}
} ;
if ( imageUrl ) {
actor . icon = {
'type' : 'Image' ,
'mediaType' : 'image/png' ,
'url' : imageUrl ,
} ;
}
2018-11-18 01:54:57 +02:00
if ( description ) {
actor . summary = ` <p> ${ description } </p> ` ;
}
2018-10-15 07:18:10 +03:00
return actor ;
}
function createWebfinger ( name , domain ) {
return {
'subject' : ` acct: ${ name } @ ${ domain } ` ,
'links' : [
{
'rel' : 'self' ,
'type' : 'application/activity+json' ,
'href' : ` https:// ${ domain } /u/ ${ name } `
}
]
} ;
}
module . exports = router ;