Compare commits

...

31 Commits

Author SHA1 Message Date
3wc 67d0315917 ' → " 2023-11-17 21:20:22 +00:00
3wc 9c8d8c89ca Add oauth2_CallbackPort 2023-11-17 21:20:22 +00:00
Paul Rodwell a38a1be4b7
Update devDepencencies for vulnerability in browserify-sign 2023-10-29 08:46:11 +00:00
Paul Rodwell ec5359de48
0.8.2 2023-10-08 18:35:57 +01:00
Paul Rodwell b3ffdd0890
Merge pull request #39 from Bortseb/patch-2
Update social.coffee
2023-10-08 18:26:11 +01:00
Robert Best 7449fdab44
Update social.coffee
We got syntax wrong. Use isnt instead of !==
2023-10-08 11:46:45 -04:00
Paul Rodwell 70cebf5ab2
0.8.1 2023-10-03 19:29:16 +01:00
Paul Rodwell 1e443f2934
update package lock 2023-10-03 19:28:49 +01:00
Paul Rodwell 95e2c76b5f
Merge pull request #38 from Bortseb/patch-1
Thanks to @Bortseb , @3-w-c , @nrn for looking into this problem.
2023-10-03 19:24:42 +01:00
Robert Best cae4118bc9
Update social.coffee
don't allow unclaimed sites to be viewed by authors not in allowed_domains.
2023-10-03 13:37:59 -04:00
Paul Rodwell d43cbe7ff6
0.8.0 2023-08-22 10:12:31 +01:00
Paul Rodwell ebcfe9cc42
Merge pull request #37 from fedwiki/paul90/login2view
Updating login to view
2023-08-22 10:09:44 +01:00
Paul Rodwell 5137dd86ac
backing off protecting assets
- breaks too many things.
2023-08-21 16:54:55 +01:00
Paul Rodwell 3305674597
reload after login, if login was required. 2023-08-21 12:19:08 +01:00
Paul Rodwell ec05842d31
protect assets and sitemap hints that login is required 2023-08-21 12:17:48 +01:00
Paul Rodwell cec8c04417
0.7.0 2023-05-01 11:29:56 +01:00
Paul Rodwell 88c15c0cef
update Authors 2023-04-27 11:11:49 +01:00
Paul Rodwell 53f8da4d4b
0.7.0-rc.0 2023-04-19 11:24:11 +01:00
Paul Rodwell 8f304374cf
Merge pull request #36 from fedwiki/paul90/jQuery
update jQuery click handlers
2023-04-19 11:22:06 +01:00
Paul Rodwell ff69116fbf
Merge branch 'master' into paul90/jQuery 2023-04-19 11:21:49 +01:00
Paul Rodwell 30a339f49a
Merge pull request #35 from fedwiki/paul90/remove-persona
remove persona
2023-04-19 11:20:12 +01:00
Paul Rodwell f7da864fdb
Merge pull request #33 from Bortseb/master
Example of admin parameter in config.json for generic OAuth
2023-04-19 11:19:51 +01:00
Paul Rodwell b2927e47c9
Better claim log message 2023-04-18 10:37:42 +01:00
Paul Rodwell 7e4e1e940d
remove modernizr 2023-04-18 10:28:00 +01:00
Paul Rodwell a0ef92ec8e
removing old persona code 2023-04-18 09:55:41 +01:00
Paul Rodwell 1d4c5d51df
update jQuery click handlers 2023-04-17 09:45:28 +01:00
Paul Rodwell f6dcb5425e
0.6.2 2023-02-07 14:49:17 +00:00
Paul Rodwell e648bf64a7
Merge pull request #34 from fedwiki/paul90/twitter-update
use @passport-js/passport-twitter
2023-02-07 14:47:22 +00:00
Paul Rodwell 32ef602460
use successRedirect
- the other documented way doesn't redirect.
2023-02-07 11:56:39 +00:00
Paul Rodwell 40afd20e4f
use @passport-js/passport-twitter 2023-02-07 11:24:58 +00:00
Robert Best f914667efe Example of admin parameter
Expands on config example to show how to specify admin ID
2022-06-10 10:58:52 -04:00
8 changed files with 610 additions and 3890 deletions

View File

@ -5,3 +5,4 @@ Ward Cunningham <ward@c2.com>
Marc-Antoine Parent <maparent@acm.org>
Ian Goodacre <Ian.Goodacre@entrain.nz>
3wc <3wc.github@doesthisthing.work>
Robert Best <chessscholar@gmail.com>

View File

@ -1,3 +0,0 @@
/*! modernizr 3.3.1 (Custom Build) | MIT *
* https://modernizr.com/download/?-fetch-promises-setclasses !*/
!function(e,n,s){function o(e,n){return typeof e===n}function i(){var e,n,s,i,a,f,l;for(var c in r)if(r.hasOwnProperty(c)){if(e=[],n=r[c],n.name&&(e.push(n.name.toLowerCase()),n.options&&n.options.aliases&&n.options.aliases.length))for(s=0;s<n.options.aliases.length;s++)e.push(n.options.aliases[s].toLowerCase());for(i=o(n.fn,"function")?n.fn():n.fn,a=0;a<e.length;a++)f=e[a],l=f.split("."),1===l.length?Modernizr[l[0]]=i:(!Modernizr[l[0]]||Modernizr[l[0]]instanceof Boolean||(Modernizr[l[0]]=new Boolean(Modernizr[l[0]])),Modernizr[l[0]][l[1]]=i),t.push((i?"":"no-")+l.join("-"))}}function a(e){var n=l.className,s=Modernizr._config.classPrefix||"";if(c&&(n=n.baseVal),Modernizr._config.enableJSClass){var o=new RegExp("(^|\\s)"+s+"no-js(\\s|$)");n=n.replace(o,"$1"+s+"js$2")}Modernizr._config.enableClasses&&(n+=" "+s+e.join(" "+s),c?l.className.baseVal=n:l.className=n)}var t=[],r=[],f={_version:"3.3.1",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,n){var s=this;setTimeout(function(){n(s[e])},0)},addTest:function(e,n,s){r.push({name:e,fn:n,options:s})},addAsyncTest:function(e){r.push({name:null,fn:e})}},Modernizr=function(){};Modernizr.prototype=f,Modernizr=new Modernizr,Modernizr.addTest("promises",function(){return"Promise"in e&&"resolve"in e.Promise&&"reject"in e.Promise&&"all"in e.Promise&&"race"in e.Promise&&function(){var n;return new e.Promise(function(e){n=e}),"function"==typeof n}()});var l=n.documentElement,c="svg"===l.nodeName.toLowerCase();Modernizr.addTest("fetch","fetch"in e),i(),a(t),delete f.addTest,delete f.addAsyncTest;for(var u=0;u<Modernizr._q.length;u++)Modernizr._q[u]();e.Modernizr=Modernizr}(window,document);

View File

@ -15,9 +15,6 @@
settings = {}
# Mozilla Persona service closes on
personaEnd = new Date('2016-11-30')
claim_wiki = () ->
# we want to initiate a claim on a wiki
#
@ -34,10 +31,13 @@ claim_wiki = () ->
.then (response) ->
if response.ok
response.json().then (json) ->
ownerName = json.ownerName
window.isClaimed = true
window.isOwner = true
update_footer ownerName, true
if wiki.lineup.bestTitle() is 'Login Required'
location.reload()
else
ownerName = json.ownerName
window.isClaimed = true
window.isOwner = true
update_footer ownerName, true
else
console.log 'Attempt to claim site failed', response
@ -59,7 +59,7 @@ update_footer = (ownerName, isAuthenticated) ->
logoutTitle = "Not Owner : Sign-out"
logoutIconClass = 'fa fa-lock fa-lg fa-fw notOwner'
$('footer > #security').append "<a href='#' id='logout' class='footer-item' title='#{logoutTitle}'><i class='#{logoutIconClass}'></i></a>"
$('footer > #security > #logout').click (e) ->
$('footer > #security > #logout').on 'click', (e) ->
e.preventDefault()
myInit = {
method: 'GET'
@ -79,63 +79,16 @@ update_footer = (ownerName, isAuthenticated) ->
# These probably should move into a menu, but this is far easier to begin with
if !isClaimed
$('footer > #security').append "<a href='#' id='claim' class='foot-item' title='Claim this Wiki'><i class='fa fa-key fa-lg fa-fw'></i></a>"
$('footer > #security > #claim').click (e) ->
$('footer > #security > #claim').on 'click', (e) ->
e.preventDefault()
claim_wiki()
else
# only offer to add alternative id if using persona - at least initially.
if settings.usingPersona
$('footer > #security').append "<a href='#' id='addAltAuth' class='foot-item' title='Add Alternative Credentials'><i class='fa fa-user-plus fa-lg fa-fw'></i></a>"
$('footer > #security > #addAltAuth').click (e) ->
e.preventDefault
document.cookie = "wikiName=#{window.location.host}" + ";domain=.#{settings.cookieDomain}; path=/; max-age=300; sameSite=Strict;"
w = WinChan.open({
url: settings.dialogAddAltURL
relay_url: settings.relayURL
window_features: "menubar=0, location=0, resizable=0, scrollbars=1, status=0, dialog=1, width=700, height=375"
params: {}
}, (err, r) ->
if err
console.log err
else
# add call to add alternative to owner here
console.log 'send request to add owner identity'
myInit = {
method: 'GET'
cache: 'no-cache'
mode: 'same-origin'
credentials: 'include'
}
fetch '/auth/addAltAuth', myInit
.then (response) ->
if response.ok
console.log 'Alternative Identity added', response
settings.usingPersona = false
if settings.wikiHost
dialogHost = settings.wikiHost
else
dialogHost = window.location.hostname
settings.cookieDomain = dialogHost
if settings.useHttps
dialogProtocol = 'https:'
else
dialogProtocol = window.location.protocol
if window.location.port
dialogHost = dialogHost + ':' + window.location.port
settings.dialogURL = dialogProtocol + '//' + dialogHost + '/auth/loginDialog'
update_footer ownerName, isAuthenticated
else
console.log 'Attempt to claim site failed', response
)
else
if !isClaimed
signonTitle = 'Claim this Wiki'
else
signonTitle = 'Wiki Owner Sign-on'
$('footer > #security').append "<a href='#' id='show-security-dialog' class='footer-item' title='#{signonTitle}'><i class='fa fa-lock fa-lg fa-fw'></i></a>"
$('footer > #security > #show-security-dialog').click (e) ->
$('footer > #security > #show-security-dialog').on 'click', (e) ->
e.preventDefault()
document.cookie = "wikiName=#{window.location.host}" + ";domain=.#{settings.cookieDomain}; path=/; max-age=300; sameSite=Strict;"
@ -153,7 +106,10 @@ update_footer = (ownerName, isAuthenticated) ->
if !isClaimed
claim_wiki()
else
update_footer ownerName, true)
if wiki.lineup.bestTitle() is 'Login Required'
location.reload()
else
update_footer ownerName, true)
@ -187,49 +143,36 @@ setup = (user) ->
lastCookie = currentCookie
, 100
wiki.getScript '/security/modernizr-custom.js', () ->
console.log 'modernizr loaded'
unless Modernizr.promises
require('es6-promise').polyfill()
unless Modernizr.fetch
require('whatwg-fetch')
wiki.getScript '/security/winchan.js'
if (!$("link[href='/security/style.css']").length)
$('<link rel="stylesheet" href="/security/style.css">').appendTo("head")
myInit = {
method: 'GET'
cache: 'no-cache'
mode: 'same-origin'
}
fetch '/auth/client-settings.json', myInit
.then (response) ->
if response.ok
response.json().then (json) ->
window.isOwner = json.isOwner
settings = json
if settings.wikiHost
dialogHost = settings.wikiHost
else
dialogHost = window.location.hostname
settings.cookieDomain = dialogHost
if settings.useHttps
dialogProtocol = 'https:'
else
dialogProtocol = window.location.protocol
if window.location.port
dialogHost = dialogHost + ':' + window.location.port
if settings.usingPersona
settings.dialogURL = dialogProtocol + '//' + dialogHost + '/auth/personaLogin'
else
settings.dialogURL = dialogProtocol + '//' + dialogHost + '/auth/loginDialog'
settings.relayURL = dialogProtocol + '//' + dialogHost + '/auth/relay.html'
settings.dialogAddAltURL = dialogProtocol + '//' + dialogHost + '/auth/addAuthDialog'
update_footer ownerName, isAuthenticated
else
console.log 'Unable to fetch client settings: ', response
wiki.getScript '/security/winchan.js'
if (!$("link[href='/security/style.css']").length)
$('<link rel="stylesheet" href="/security/style.css">').appendTo("head")
myInit = {
method: 'GET'
cache: 'no-cache'
mode: 'same-origin'
}
fetch '/auth/client-settings.json', myInit
.then (response) ->
if response.ok
response.json().then (json) ->
window.isOwner = json.isOwner
settings = json
if settings.wikiHost
dialogHost = settings.wikiHost
else
dialogHost = window.location.hostname
settings.cookieDomain = dialogHost
if settings.useHttps
dialogProtocol = 'https:'
else
dialogProtocol = window.location.protocol
if window.location.port
dialogHost = dialogHost + ':' + window.location.port
settings.dialogURL = dialogProtocol + '//' + dialogHost + '/auth/loginDialog'
settings.relayURL = dialogProtocol + '//' + dialogHost + '/auth/relay.html'
settings.dialogAddAltURL = dialogProtocol + '//' + dialogHost + '/auth/addAuthDialog'
update_footer ownerName, isAuthenticated
else
console.log 'Unable to fetch client settings: ', response
window.plugins.security = {setup, claim_wiki, update_footer}

View File

@ -35,6 +35,7 @@ Sometimes, you'll be able to look up the URLs by visiting your provider's
```JSON
{
"farm": true,
"admin": {"oauth2": "ID VALUE FROM OWNER.JSON FILE OF ADMIN"},
"security_type": "passportjs",
"oauth2_clientID": "CLIENT ID",
"oauth2_clientSecret": "CLIENT SECRET",
@ -48,6 +49,7 @@ Sometimes, you'll be able to look up the URLs by visiting your provider's
```JSON
{
"farm": true,
"admin": {"oauth2": "ID VALUE FROM OWNER.JSON FILE OF ADMIN"},
"security_type": "passportjs",
"oauth2_clientID": "CLIENT ID",
"oauth2_clientSecret": "CLIENT SECRET",

View File

@ -9,7 +9,7 @@ Configuration of Passport security plug-ins is a two stage process:
The legacy Mozilla Persona Passport plug-in does not require any configuration.
This plug-in comes with support for using GitHub, Google, and Twitter. Although the configuration process is broadly the same for each of these, there are some slight differences.
This plug-in comes with support for using GitHub, Google, Twitter, and generic OAuth. Although the configuration process is broadly the same for each of these, there are some slight differences.
As a wiki server owner you need to pick one, or more, of these that you want to use.

4115
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +1,17 @@
{
"name": "wiki-security-passportjs",
"version": "0.6.1",
"version": "0.8.2",
"description": "Security plugin for Federated Wiki, using passport.js",
"author": "Paul Rodwell <paul.rodwell@btinternet.com> (http://rodwell.me)",
"license": "MIT",
"dependencies": {
"@passport-js/passport-twitter": "^1.0.8",
"coffeescript": "^2.4.1",
"es6-promise": "^4.2.8",
"lodash": "^4.17.19",
"passport": "^0.3.2",
"passport-github2": "^0.1.12",
"passport-google-oauth20": "^2.0.0",
"passport-oauth2": "^1.6.1",
"passport-twitter": "github:paul90/passport-twitter#48b52556f48e4e8f7c55288baaf3ba3076eeba16",
"persona-pass": "^0.2.1",
"qs": "^6.7.0",
"whatwg-fetch": "^3.2.0"
"passport-oauth2": "^1.6.1"
},
"devDependencies": {
"coffeeify": "^3.0.1",

View File

@ -11,7 +11,6 @@ fs = require 'fs'
path = require 'path'
https = require 'https'
qs = require 'qs'
url = require 'url'
@ -38,7 +37,6 @@ module.exports = exports = (log, loga, argv) ->
statusDir = argv.status
idFile = argv.id
usingPersona = false
if argv.security_useHttps
useHttps = true
@ -53,29 +51,13 @@ module.exports = exports = (log, loga, argv) ->
callbackHost = callbackHost + ":" + url.parse(argv.url).port
else
callbackHost = url.parse(argv.url).host
if argv.oauth2_CallbackPort?
callbackHost = callbackHost + ":" + argv.oauth2_CallbackPort
console.log "callbackHost", callbackHost
ids = []
# Mozilla Persona service closes on
personaEnd = new Date('2016-11-30')
watchForOwnerChange = ->
# we watch for owner changes, so we can update the information held here
fs.watch(idFile, (eventType, filename) ->
# re-read the owner file
fs.readFile(idFile, (err, data) ->
if err
console.log 'Error reading ', idFile, err
return
owner = JSON.parse(data)
usingPersona = false
if _.isEmpty(_.intersection(_.keys(owner), ids))
if _.has(owner, 'persona')
usingPersona = true
ownerName = owner.name
)
)
#### Public stuff ####
# Attempt to figure out if the wiki is claimed or not,
@ -87,11 +69,6 @@ module.exports = exports = (log, loga, argv) ->
fs.readFile(idFile, (err, data) ->
if err then return cb err
owner = JSON.parse(data)
# we only enable persona if it is the only owner information.
if _.isEmpty(_.intersection(_.keys(owner), ids))
if _.has(owner, 'persona')
usingPersona = true
watchForOwnerChange()
cb())
else
owner = ''
@ -109,10 +86,9 @@ module.exports = exports = (log, loga, argv) ->
if !exists
fs.writeFile(idFile, JSON.stringify(id), (err) ->
if err then return cb err
console.log "Claiming wiki #{wikiName} for #{id}"
console.log "Claiming wiki #{wikiName} for #{id.name}"
owner = id
ownerName = owner.name
watchForOwnerChange()
cb())
else
cb('Already Claimed')
@ -140,11 +116,6 @@ module.exports = exports = (log, loga, argv) ->
return true
else
return false
when 'persona'
if _.isEqual(owner[idProvider].email, req.session.passport.user[idProvider].email)
return true
else
return false
else
return false
catch error
@ -165,16 +136,11 @@ module.exports = exports = (log, loga, argv) ->
return false
switch idProvider
when "github", "google", "twitter", 'oauth2'
when "github", "google", "twitter", "oauth2"
if _.isEqual(admin[idProvider], req.session.passport.user[idProvider].id)
return true
else
return false
when "persona"
if _.isEqual(admin[idProvider], req.session.passport.user[idProvider].email)
return true
else
return false
else
return false
@ -200,12 +166,13 @@ module.exports = exports = (log, loga, argv) ->
OAuth2Strategy = require('passport-oauth2').Strategy
oauth2StrategyName = callbackHost + 'OAuth'
console.log "callbackHost", callbackHost
if argv.oauth2_UserInfoURL?
OAuth2Strategy::userProfile = (accesstoken, done) ->
console.log "hello"
console.log accesstoken
@_oauth2._request "GET", argv.oauth2_UserInfoURL, null, null, accesstoken, (err, data) ->
console.log "data", data
console.log "err", err
if err
return done err
try
@ -288,7 +255,7 @@ module.exports = exports = (log, loga, argv) ->
# Twitter Strategy
if argv.twitter_consumerKey? and argv.twitter_consumerSecret?
ids.push('twitter')
TwitterStrategy = require('passport-twitter').Strategy
TwitterStrategy = require('@passport-js/passport-twitter').Strategy
twitterStrategyName = callbackHost + 'Twitter'
@ -323,24 +290,6 @@ module.exports = exports = (log, loga, argv) ->
}
cb(null, user)))
# Persona Strategy
PersonaStrategy = require('persona-pass').Strategy
personaAudience = callbackProtocol + '//' + callbackHost
personaStrategyName = callbackHost + 'Persona'
passport.use(personaStrategyName, new PersonaStrategy({
audience: personaAudience
}, (email, cb) ->
user = {
persona: {
email: email
}
}
cb(null, user)))
app.use(passport.initialize())
app.use(passport.session())
@ -367,16 +316,11 @@ module.exports = exports = (log, loga, argv) ->
app.get('/auth/google/callback',
passport.authenticate(googleStrategyName, { prompt: 'select_account', successRedirect: '/auth/loginDone', failureRedirect: '/auth/loginDialog'}))
# Persona
app.post('/auth/browserid',
passport.authenticate(personaStrategyName, { successRedirect: '/auth/loginDone', failureRedirect: '/auth/loginDialog'}))
app.get '/auth/client-settings.json', (req, res) ->
# the client needs some information to configure itself
settings = {
useHttps: useHttps
usingPersona: usingPersona
}
if wikiHost
settings.wikiHost = wikiHost
@ -417,47 +361,6 @@ module.exports = exports = (log, loga, argv) ->
}
res.render(path.join(__dirname, '..', 'views', 'securityDialog.html'), info)
app.get '/auth/personaLogin', (req, res) ->
cookies = req.cookies
schemeButtons = []
if Date.now() < personaEnd
schemeButtons.push({
button: "<a href='#' id='browserid' class='scheme-button persona-button'><span>Persona</span></a>
<script>
$('#browserid').click(function(){
navigator.id.get(function(assertion) {
if (assertion) {
$('input').val(assertion);
$('form').submit();
} else {
location.reload();
}
});
});
</script>"})
info = {
wikiName: cookies['wikiName']
wikiHostName: if wikiHost
"part of " + req.hostname + " wiki farm"
else
"a federated wiki site"
title: "Federated Wiki: Site Owner Sign-on"
loginText: "Sign in to"
message: "Mozilla Persona closes on 30th November 2016. Wiki owners should add an alternative identity as soon as they are able."
schemes: schemeButtons
}
else
info = {
wikiName: cookies['wikiName']
wikiHostName: if wikiHost
"part of " + req.hostname + " wiki farm"
else
"a federated wiki site"
title: "Federated Wiki: Site Owner Sign-on"
message: "Mozilla Persona has now closed. Wiki owners will need to contact the Wiki Farm owner to re-claim their wiki."
}
res.render(path.join(__dirname, '..', 'views', 'personaDialog.html'), info)
app.get '/auth/loginDone', (req, res) ->
cookies = req.cookies
@ -502,15 +405,17 @@ module.exports = exports = (log, loga, argv) ->
false
app.all '*', (req, res, next) ->
# todo: think about assets??
# don't protect site flag,
return next() if req.url is '/favicon.png'
return next() unless /\.(json|html)$/.test req.url
# prepare to examine remote server's forwarded session
res.header 'Access-Control-Allow-Origin', req.get('Origin')||'*'
res.header 'Access-Control-Allow-Credentials', 'true'
return next() if isAuthorized(req) || allowedToView(req)
# protect unclaimed by adding "add owner isnt ''" - maybe via parameter
return next() if (isAuthorized(req) and (owner isnt '')) or allowedToView(req)
return res.redirect("/view/#{m[1]}") if m = req.url.match /\/(.*)\.html/
return res.json([]) if req.url == '/system/sitemap.json'
return res.json(['Login Required']) if req.url == '/system/sitemap.json'
# not happy, explain why these pages can't be viewed
problem = "This is a restricted wiki requires users to login to view pages. You do not have to be the site owner but you do need to login with a participating email address."
@ -569,94 +474,12 @@ module.exports = exports = (log, loga, argv) ->
console.log 'rejecting - not authorized', req.path
res.sendStatus(403)
app.get '/auth/addAltAuth', authorized, (req, res) ->
# add alternative authorentication scheme - only makes sense if user owns this site
res.status(202).end()
user = req.session.passport.user
idProviders = _.keys(user)
userIds = {}
idProviders.forEach (idProvider) ->
id = switch idProvider
when "oauth2" then {
name: user.oauth2.displayName
oauth2: {
id: user.oauth2.id
username: user.oauth2.username
}
}
when "twitter" then {
name: user.twitter.displayName
twitter: {
id: user.twitter.id
username: user.twitter.username
}
}
when "github" then {
name: user.github.displayName
github: {
id: user.github.id
username: user.github.username
email: user.github.emails
}
}
when "google" then {
name: user.google.displayName
google: {
id: user.google.id
emails: user.google.emails
}
}
# only needed until persona closes
when "persona" then {
name: user.persona.email
.substr(0, user.persona.email.indexOf('@'))
.split('.')
.join(' ')
.toLowerCase()
.replace(/(^| )(\w)/g, (x) ->
return x.toUpperCase())
persona: {
email: user.persona.email
}
}
userIds = _.merge(userIds, id)
wikiDir = path.resolve(argv.data, '..')
statusDir = argv.status.split(path.sep).slice(-1)[0]
idFileName = path.parse(idFile).base
pattern = '*/' + statusDir + '/' + idFileName
glob(pattern, {cwd: wikiDir}, (err, files) ->
_.forEach files, (file) ->
# are we the owner?
fs.readFile(path.join(wikiDir, file), 'utf8', (err, data) ->
if err
console.log 'Error reading ', file, err
return
siteOwner = JSON.parse(data)
if _.intersectionWith(_.entries(siteOwner), _.entries(user), _.isEqual).length > 0
updateOwner = _.merge(user, siteOwner)
fs.writeFile(path.join(wikiDir, file), JSON.stringify(userIds), (err) ->
if err
console.log 'Error writing ', file, err
# if the write works the change will be picked up by fs.watch() in watchForOwnerChange
# so there is nothing more to do here.
)
)
)
app.get '/auth/claim-wiki', (req, res) ->
if owner
console.log 'Claim Request Ignored: Wiki already has owner - ', wikiName
res.sendStatus(403)
else
user = req.session.passport.user
# there can be more than one id provider - initially only if we logged in with persona
idProviders = _.keys(user)
id = {}
@ -691,19 +514,6 @@ module.exports = exports = (log, loga, argv) ->
emails: user.google.emails
}
}
# only needed until persona closes
when "persona" then {
name: user.persona.email
.substr(0, user.persona.email.indexOf('@'))
.split('.')
.join(' ')
.toLowerCase()
.replace(/(^| )(\w)/g, (x) ->
return x.toUpperCase())
persona: {
email: user.persona.email
}
}
if _.isEmpty(id)
console.log 'Unable to claim wiki', req.hostname, ' no valid id provided'