Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
60003d64d5
|
|||
|
535dde13ff
|
|||
|
63d102296f
|
|||
|
77d203b2b0
|
|||
|
fcbf25e3ce
|
|||
|
084ec7bbc1
|
|||
|
6b3339a883
|
|||
|
8f1bbfef56
|
35
app/assets/error-log.js
Normal file
35
app/assets/error-log.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
window.COREID_ERROR_LOG_URL = window.COREID_ERROR_LOG_URL || '/api/v1/log-error'
|
||||||
|
|
||||||
|
async function logError(error) {
|
||||||
|
try {
|
||||||
|
await fetch(window.COREID_ERROR_LOG_URL, {
|
||||||
|
method: 'POST',
|
||||||
|
cache: 'no-cache',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
full_url: window.location.href,
|
||||||
|
trace: [
|
||||||
|
error.name + ': ' + error.message,
|
||||||
|
error.stack,
|
||||||
|
].join('\n')
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
;(function() {
|
||||||
|
var old_onerror = window.onerror
|
||||||
|
|
||||||
|
window.onerror = function(msg, src, line, col, error) {
|
||||||
|
logError(error).then(function() {
|
||||||
|
if ( typeof old_onerror === 'function' ) {
|
||||||
|
try {
|
||||||
|
old_onerror(msg, src, line, col, error)
|
||||||
|
} catch(e) {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})()
|
||||||
@@ -18,6 +18,11 @@ class CoreIDAdapter {
|
|||||||
expiresAt = new Date(Date.now() + (expiresIn * 1000))
|
expiresAt = new Date(Date.now() + (expiresIn * 1000))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( payload.uid ) {
|
||||||
|
payload.originalUid = payload.uid
|
||||||
|
payload.uid = payload.uid.toLowerCase()
|
||||||
|
}
|
||||||
|
|
||||||
await this.coll().updateOne(
|
await this.coll().updateOne(
|
||||||
{ _id },
|
{ _id },
|
||||||
{ $set: { payload, ...(expiresAt ? { expiresAt } : undefined) } },
|
{ $set: { payload, ...(expiresAt ? { expiresAt } : undefined) } },
|
||||||
@@ -34,6 +39,11 @@ class CoreIDAdapter {
|
|||||||
).limit(1).next()
|
).limit(1).next()
|
||||||
|
|
||||||
if (!result) return undefined
|
if (!result) return undefined
|
||||||
|
|
||||||
|
if ( result?.payload?.originalUid ) {
|
||||||
|
result.payload.uid = result.payload.originalUid
|
||||||
|
}
|
||||||
|
|
||||||
return result.payload
|
return result.payload
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,6 +64,11 @@ class CoreIDAdapter {
|
|||||||
).limit(1).next()
|
).limit(1).next()
|
||||||
|
|
||||||
if (!result) return undefined
|
if (!result) return undefined
|
||||||
|
|
||||||
|
if ( result?.payload?.originalUid ) {
|
||||||
|
result.payload.uid = result.payload.originalUid
|
||||||
|
}
|
||||||
|
|
||||||
return result.payload
|
return result.payload
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,12 @@ class Home extends Controller {
|
|||||||
async tmpl(req, res) {
|
async tmpl(req, res) {
|
||||||
return res.page('tmpl', {...this.Vue.data(), ...this.Vue.session(req)})
|
return res.page('tmpl', {...this.Vue.data(), ...this.Vue.session(req)})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async log_front_end_error(req, res, next) {
|
||||||
|
const FrontEndError = this.models.get('FrontEndError')
|
||||||
|
await FrontEndError.log(req)
|
||||||
|
return res.api()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Home
|
module.exports = Home
|
||||||
|
|||||||
@@ -119,14 +119,12 @@ class OpenIDController extends Controller {
|
|||||||
uid, prompt, params, session,
|
uid, prompt, params, session,
|
||||||
} = await this.openid_connect.provider.interactionDetails(req, res)
|
} = await this.openid_connect.provider.interactionDetails(req, res)
|
||||||
|
|
||||||
console.log({uid, prompt, params, session})
|
|
||||||
|
|
||||||
const name = prompt.name
|
const name = prompt.name
|
||||||
if ( typeof this[name] !== 'function' ) {
|
if ( typeof this[name] !== 'function' ) {
|
||||||
return this.fail(res, 'Sorry, something has gone wrong.')
|
return this.fail(res, 'Sorry, something has gone wrong.')
|
||||||
}
|
}
|
||||||
|
|
||||||
return this[name](req, res, { uid: uid, prompt, params, session })
|
return this[name](req, res, { uid: uid.toLowerCase(), prompt, params, session })
|
||||||
}
|
}
|
||||||
|
|
||||||
async consent(req, res, { uid, prompt, params, session }) {
|
async consent(req, res, { uid, prompt, params, session }) {
|
||||||
@@ -142,13 +140,13 @@ class OpenIDController extends Controller {
|
|||||||
const Policy = this.models.get('iam:Policy')
|
const Policy = this.models.get('iam:Policy')
|
||||||
const application = await Application.findOne({ openid_client_ids: params.client_id })
|
const application = await Application.findOne({ openid_client_ids: params.client_id })
|
||||||
if ( !application ) {
|
if ( !application ) {
|
||||||
this.output.warning('IAM Denial!')
|
this.output.warn('IAM Denial!')
|
||||||
return this.Vue.auth_message(res, {
|
return this.Vue.auth_message(res, {
|
||||||
message: req.T('saml.no_access').replace('APP_NAME', 'this application'),
|
message: req.T('saml.no_access').replace('APP_NAME', 'this application'),
|
||||||
next_destination: '/dash',
|
next_destination: '/dash',
|
||||||
})
|
})
|
||||||
} else if ( !(await Policy.check_user_access(req.user, application.id)) ) {
|
} else if ( !(await Policy.check_user_access(req.user, application.id)) ) {
|
||||||
this.output.warning('IAM Denial!')
|
this.output.warn('IAM Denial!')
|
||||||
return this.Vue.auth_message(res, {
|
return this.Vue.auth_message(res, {
|
||||||
message: req.T('saml.no_access').replace('APP_NAME', application.name),
|
message: req.T('saml.no_access').replace('APP_NAME', application.name),
|
||||||
next_destination: '/dash',
|
next_destination: '/dash',
|
||||||
@@ -172,7 +170,7 @@ class OpenIDController extends Controller {
|
|||||||
{
|
{
|
||||||
text: req.T('common.grant'),
|
text: req.T('common.grant'),
|
||||||
action: 'redirect',
|
action: 'redirect',
|
||||||
next: `/openid/interaction/${uid}/grant`,
|
next: `/openid/interaction/${uid.toLowerCase()}/grant`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@@ -180,7 +178,7 @@ class OpenIDController extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async login(req, res, { uid, prompt, params, session }) {
|
async login(req, res, { uid, prompt, params, session }) {
|
||||||
return res.redirect(`/openid/interaction/${uid}/start-session`)
|
return res.redirect(`/openid/interaction/${uid.toLowerCase()}/start-session`)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -202,13 +200,13 @@ class OpenIDController extends Controller {
|
|||||||
const Policy = this.models.get('iam:Policy')
|
const Policy = this.models.get('iam:Policy')
|
||||||
const application = await Application.findOne({ openid_client_ids: params.client_id })
|
const application = await Application.findOne({ openid_client_ids: params.client_id })
|
||||||
if ( !application ) {
|
if ( !application ) {
|
||||||
this.output.warning('IAM Denial!')
|
this.output.warn('IAM Denial!')
|
||||||
return this.Vue.auth_message(res, {
|
return this.Vue.auth_message(res, {
|
||||||
message: req.T('saml.no_access').replace('APP_NAME', 'this application'),
|
message: req.T('saml.no_access').replace('APP_NAME', 'this application'),
|
||||||
next_destination: '/dash',
|
next_destination: '/dash',
|
||||||
})
|
})
|
||||||
} else if ( !(await Policy.check_user_access(req.user, application.id)) ) {
|
} else if ( !(await Policy.check_user_access(req.user, application.id)) ) {
|
||||||
this.output.warning('IAM Denial!')
|
this.output.warn('IAM Denial!')
|
||||||
return this.Vue.auth_message(res, {
|
return this.Vue.auth_message(res, {
|
||||||
message: req.T('saml.no_access').replace('APP_NAME', application.name),
|
message: req.T('saml.no_access').replace('APP_NAME', application.name),
|
||||||
next_destination: '/dash',
|
next_destination: '/dash',
|
||||||
@@ -238,13 +236,13 @@ class OpenIDController extends Controller {
|
|||||||
const Policy = this.models.get('iam:Policy')
|
const Policy = this.models.get('iam:Policy')
|
||||||
const application = await Application.findOne({ openid_client_ids: params.client_id })
|
const application = await Application.findOne({ openid_client_ids: params.client_id })
|
||||||
if ( !application ) {
|
if ( !application ) {
|
||||||
this.output.warning('IAM Denial!')
|
this.output.warn('IAM Denial!')
|
||||||
return this.Vue.auth_message(res, {
|
return this.Vue.auth_message(res, {
|
||||||
message: req.T('saml.no_access').replace('APP_NAME', 'this application'),
|
message: req.T('saml.no_access').replace('APP_NAME', 'this application'),
|
||||||
next_destination: '/dash',
|
next_destination: '/dash',
|
||||||
})
|
})
|
||||||
} else if ( !(await Policy.check_user_access(req.user, application.id)) ) {
|
} else if ( !(await Policy.check_user_access(req.user, application.id)) ) {
|
||||||
this.output.warning('IAM Denial!')
|
this.output.warn('IAM Denial!')
|
||||||
return this.Vue.auth_message(res, {
|
return this.Vue.auth_message(res, {
|
||||||
message: req.T('saml.no_access').replace('APP_NAME', application.name),
|
message: req.T('saml.no_access').replace('APP_NAME', application.name),
|
||||||
next_destination: '/dash',
|
next_destination: '/dash',
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ const Oauth2Controller = require('flitter-auth/controllers/Oauth2')
|
|||||||
*/
|
*/
|
||||||
class Oauth2 extends Oauth2Controller {
|
class Oauth2 extends Oauth2Controller {
|
||||||
static get services() {
|
static get services() {
|
||||||
return [...super.services, 'Vue', 'configs', 'models']
|
return [...super.services, 'Vue', 'configs', 'models', 'output']
|
||||||
}
|
}
|
||||||
|
|
||||||
async authorize_post(req, res, next) {
|
async authorize_post(req, res, next) {
|
||||||
@@ -18,6 +18,24 @@ class Oauth2 extends Oauth2Controller {
|
|||||||
const StarshipClient = this.models.get('oauth:Client')
|
const StarshipClient = this.models.get('oauth:Client')
|
||||||
const starship_client = await StarshipClient.findOne({ active: true, uuid: client.clientID })
|
const starship_client = await StarshipClient.findOne({ active: true, uuid: client.clientID })
|
||||||
|
|
||||||
|
// Make sure the user has IAM access before proceeding
|
||||||
|
const Application = this.models.get('Application')
|
||||||
|
const Policy = this.models.get('iam:Policy')
|
||||||
|
const application = await Application.findOne({ oauth_client_ids: starship_client.id })
|
||||||
|
if ( !application ) {
|
||||||
|
this.output.warn('IAM Denial!')
|
||||||
|
return this.Vue.auth_message(res, {
|
||||||
|
message: req.T('saml.no_access').replace('APP_NAME', application.name),
|
||||||
|
next_destination: '/dash',
|
||||||
|
})
|
||||||
|
} else if ( !(await Policy.check_user_access(req.user, application.id)) ) {
|
||||||
|
this.output.warn('IAM Denial!')
|
||||||
|
return this.Vue.auth_message(res, {
|
||||||
|
message: req.T('saml.no_access').replace('APP_NAME', application.name),
|
||||||
|
next_destination: '/dash',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
req.user.authorize(starship_client)
|
req.user.authorize(starship_client)
|
||||||
await req.user.save()
|
await req.user.save()
|
||||||
return super.authorize_post(req, res, next)
|
return super.authorize_post(req, res, next)
|
||||||
@@ -31,6 +49,24 @@ class Oauth2 extends Oauth2Controller {
|
|||||||
const StarshipClient = this.models.get('oauth:Client')
|
const StarshipClient = this.models.get('oauth:Client')
|
||||||
const starship_client = await StarshipClient.findOne({ active: true, uuid: client.clientID })
|
const starship_client = await StarshipClient.findOne({ active: true, uuid: client.clientID })
|
||||||
|
|
||||||
|
// Make sure the user has IAM access before proceeding
|
||||||
|
const Application = this.models.get('Application')
|
||||||
|
const Policy = this.models.get('iam:Policy')
|
||||||
|
const application = await Application.findOne({ oauth_client_ids: starship_client.id })
|
||||||
|
if ( !application ) {
|
||||||
|
this.output.warn('IAM Denial!')
|
||||||
|
return this.Vue.auth_message(res, {
|
||||||
|
message: req.T('saml.no_access').replace('APP_NAME', application.name),
|
||||||
|
next_destination: '/dash',
|
||||||
|
})
|
||||||
|
} else if ( !(await Policy.check_user_access(req.user, application.id)) ) {
|
||||||
|
this.output.warn('IAM Denial!')
|
||||||
|
return this.Vue.auth_message(res, {
|
||||||
|
message: req.T('saml.no_access').replace('APP_NAME', application.name),
|
||||||
|
next_destination: '/dash',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if ( req.user.has_authorized(starship_client) ) {
|
if ( req.user.has_authorized(starship_client) ) {
|
||||||
return this.Vue.invoke_action(res, {
|
return this.Vue.invoke_action(res, {
|
||||||
text: 'Grant Access',
|
text: 'Grant Access',
|
||||||
|
|||||||
29
app/models/FrontEndError.model.js
Normal file
29
app/models/FrontEndError.model.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
const { Model } = require('flitter-orm')
|
||||||
|
|
||||||
|
class FrontEndErrorModel extends Model {
|
||||||
|
static get schema() {
|
||||||
|
return {
|
||||||
|
user_agent: String,
|
||||||
|
logged_at: { type: Date, default: () => new Date },
|
||||||
|
user_id: String,
|
||||||
|
session_id: String,
|
||||||
|
full_url: String,
|
||||||
|
trace: String,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async log(request) {
|
||||||
|
const err = new this({
|
||||||
|
user_agent: request.get('user-agent'),
|
||||||
|
user_id: request?.user?.id,
|
||||||
|
session_id: request.sessionID,
|
||||||
|
full_url: request.body.full_url,
|
||||||
|
trace: request.body.trace,
|
||||||
|
})
|
||||||
|
|
||||||
|
await err.save()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = exports = FrontEndErrorModel
|
||||||
@@ -8,6 +8,7 @@ class PermissionMiddleware extends Middleware {
|
|||||||
async test(req, res, next, { check }) {
|
async test(req, res, next, { check }) {
|
||||||
const Policy = this.models.get('iam:Policy')
|
const Policy = this.models.get('iam:Policy')
|
||||||
|
|
||||||
|
if ( !req.additional_api_log_data ) req.additional_api_log_data = {}
|
||||||
req.additional_api_log_data.permission_check = check
|
req.additional_api_log_data.permission_check = check
|
||||||
|
|
||||||
// If the request was authorized using an OAuth2 bearer token,
|
// If the request was authorized using an OAuth2 bearer token,
|
||||||
|
|||||||
@@ -59,6 +59,10 @@ const index = {
|
|||||||
'middleware::auth:GuestOnly',
|
'middleware::auth:GuestOnly',
|
||||||
'controller::api:v1:Password.request_reset',
|
'controller::api:v1:Password.request_reset',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
'/api/v1/log-error': [
|
||||||
|
'controller::Home.log_front_end_error'
|
||||||
|
],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ html(lang='en')
|
|||||||
.app-container
|
.app-container
|
||||||
block app
|
block app
|
||||||
block script
|
block script
|
||||||
|
script(src='/assets/error-log.js')
|
||||||
script(src='/assets/lib/axios/axios.min.js')
|
script(src='/assets/lib/axios/axios.min.js')
|
||||||
script(src='/assets/lib/jquery/jquery-3.4.1.slim.min.js')
|
script(src='/assets/lib/jquery/jquery-3.4.1.slim.min.js')
|
||||||
script(src='/assets/lib/popper/popper-1.16.0.min.js')
|
script(src='/assets/lib/popper/popper-1.16.0.min.js')
|
||||||
|
|||||||
Reference in New Issue
Block a user