mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #3543 from overleaf/jel-em-ip-matcher
IP matcher notifications GitOrigin-RevId: 50811fb683961f4d021b37b1d97c24da48c59720
This commit is contained in:
parent
b44aed56dd
commit
d612c03f8e
4 changed files with 137 additions and 69 deletions
|
@ -127,9 +127,15 @@ function ipMatcherAffiliation(userId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const key = `ip-matched-affiliation-${body.id}`
|
const key = `ip-matched-affiliation-${body.id}`
|
||||||
|
const portalPath = body.portal_slug
|
||||||
|
? `/${body.is_university ? 'edu' : 'org'}/${body.portal_slug}`
|
||||||
|
: undefined
|
||||||
const messageOpts = {
|
const messageOpts = {
|
||||||
university_name: body.name,
|
university_name: body.name,
|
||||||
content: body.enrolment_ad_html
|
institutionId: body.id,
|
||||||
|
content: body.enrolment_ad_html,
|
||||||
|
portalPath,
|
||||||
|
ssoEnabled: body.sso_enabled
|
||||||
}
|
}
|
||||||
return NotificationsHandler.createNotification(
|
return NotificationsHandler.createNotification(
|
||||||
userId,
|
userId,
|
||||||
|
|
|
@ -51,17 +51,40 @@ include ../../_mixins/saml
|
||||||
span.sr-only #{translate("close")}
|
span.sr-only #{translate("close")}
|
||||||
.alert.alert-info(
|
.alert.alert-info(
|
||||||
ng-switch-when="notification_ip_matched_affiliation"
|
ng-switch-when="notification_ip_matched_affiliation"
|
||||||
|
ng-if="notification.messageOpts.ssoEnabled"
|
||||||
)
|
)
|
||||||
.notification-body
|
.notification-body
|
||||||
| It looks like you're at
|
| !{translate("looks_like_youre_at", {institutionName: '{{notification.messageOpts.university_name}}'}, ['strong'])}
|
||||||
strong {{ notification.messageOpts.university_name }}! <br/>
|
br
|
||||||
| Did you know that {{notification.messageOpts.university_name}} is providing
|
| !{translate("you_can_now_log_in_sso", {}, ['strong'])}
|
||||||
strong free Overleaf Professional accounts
|
br
|
||||||
| to everyone at {{notification.messageOpts.university_name}}? <br/>
|
| #{translate("link_institutional_email_get_started", {}, ['strong'])}
|
||||||
| Add an institutional email address to claim your account.
|
a(
|
||||||
|
ng-href="{{notification.messageOpts.portalPath || 'https://www.overleaf.com/learn/how-to/Institutional_Login'}}"
|
||||||
|
) #{translate("find_out_more_nt")}
|
||||||
.notification-action
|
.notification-action
|
||||||
a.pull-right.btn.btn-sm.btn-info(href="/user/settings")
|
a.pull-right.btn.btn-sm.btn-info(
|
||||||
| Add Affiliation
|
href=`{{samlInitPath}}?university_id={{notification.messageOpts.institutionId}}`
|
||||||
|
)
|
||||||
|
| #{translate("link_account")}
|
||||||
|
.notification-close
|
||||||
|
button.btn-sm(ng-click="dismiss(notification)").close.pull-right
|
||||||
|
span(aria-hidden="true") ×
|
||||||
|
span.sr-only #{translate("close")}
|
||||||
|
.alert.alert-info(
|
||||||
|
ng-switch-when="notification_ip_matched_affiliation"
|
||||||
|
ng-if="!notification.messageOpts.ssoEnabled"
|
||||||
|
)
|
||||||
|
.notification-body
|
||||||
|
| !{translate("looks_like_youre_at", {institutionName: '{{notification.messageOpts.university_name}}'}, ['strong'])}
|
||||||
|
br
|
||||||
|
| !{translate("did_you_know_institution_providing_professional", {institutionName: '{{notification.messageOpts.university_name}}'}, ['strong'])}
|
||||||
|
br
|
||||||
|
| #{translate("add_email_to_claim_features")}
|
||||||
|
.notification-action
|
||||||
|
a.pull-right.btn.btn-sm.btn-info(
|
||||||
|
href="/user/settings"
|
||||||
|
) #{translate("add_affiliation")}
|
||||||
.notification-close
|
.notification-close
|
||||||
button.btn-sm(ng-click="dismiss(notification)").close.pull-right
|
button.btn-sm(ng-click="dismiss(notification)").close.pull-right
|
||||||
span(aria-hidden="true") ×
|
span(aria-hidden="true") ×
|
||||||
|
|
|
@ -1330,5 +1330,11 @@
|
||||||
"github_is_premium": "GitHub sync is a premium feature",
|
"github_is_premium": "GitHub sync is a premium feature",
|
||||||
"remote_service_error": "The remote service produced an error",
|
"remote_service_error": "The remote service produced an error",
|
||||||
"linked_file": "Imported file",
|
"linked_file": "Imported file",
|
||||||
"n_items": "__count__ items"
|
"n_items": "__count__ items",
|
||||||
|
"you_can_now_log_in_sso": "You can now log in through your institution and may receive <0>free __appName__ Professional features</0>!",
|
||||||
|
"link_institutional_email_get_started": "Link an institutional email address to your account to get started.",
|
||||||
|
"looks_like_youre_at": "It looks like you're at <0>__institutionName__</0>!",
|
||||||
|
"add_affiliation": "Add Affiliation",
|
||||||
|
"did_you_know_institution_providing_professional": "Did you know that __institutionName__ is providing <0>free __appName__ Professional features</0> to everyone at __institutionName__?",
|
||||||
|
"add_email_to_claim_features": "Add an institutional email address to claim your features."
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,4 @@
|
||||||
/* eslint-disable
|
|
||||||
camelcase,
|
|
||||||
max-len,
|
|
||||||
no-return-assign,
|
|
||||||
no-unused-vars,
|
|
||||||
*/
|
|
||||||
// TODO: This file was created by bulk-decaffeinate.
|
|
||||||
// Fix any style issues and re-enable lint.
|
|
||||||
/*
|
|
||||||
* decaffeinate suggestions:
|
|
||||||
* DS102: Remove unnecessary code created because of implicit returns
|
|
||||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
||||||
*/
|
|
||||||
const SandboxedModule = require('sandboxed-module')
|
const SandboxedModule = require('sandboxed-module')
|
||||||
const { assert } = require('chai')
|
|
||||||
require('chai').should()
|
require('chai').should()
|
||||||
const sinon = require('sinon')
|
const sinon = require('sinon')
|
||||||
const modulePath = require('path').join(
|
const modulePath = require('path').join(
|
||||||
|
@ -21,19 +7,14 @@ const modulePath = require('path').join(
|
||||||
)
|
)
|
||||||
|
|
||||||
describe('NotificationsBuilder', function() {
|
describe('NotificationsBuilder', function() {
|
||||||
const user_id = '123nd3ijdks'
|
const userId = '123nd3ijdks'
|
||||||
|
|
||||||
|
describe('ipMatcherAffiliation', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
this.handler = { createNotification: sinon.stub().callsArgWith(6) }
|
this.handler = { createNotification: sinon.stub().callsArgWith(6) }
|
||||||
|
|
||||||
this.settings = { apis: { v1: { url: 'v1.url', user: '', pass: '' } } }
|
this.settings = { apis: { v1: { url: 'v1.url', user: '', pass: '' } } }
|
||||||
this.body = { id: 1, name: 'stanford', enrolment_ad_html: 'v1 ad content' }
|
this.request = sinon.stub()
|
||||||
const response = { statusCode: 200 }
|
this.controller = SandboxedModule.require(modulePath, {
|
||||||
this.request = sinon
|
|
||||||
.stub()
|
|
||||||
.returns(this.stubResponse)
|
|
||||||
.callsArgWith(1, null, response, this.body)
|
|
||||||
return (this.controller = SandboxedModule.require(modulePath, {
|
|
||||||
globals: {
|
globals: {
|
||||||
console: console
|
console: console
|
||||||
},
|
},
|
||||||
|
@ -46,28 +27,80 @@ describe('NotificationsBuilder', function() {
|
||||||
err() {}
|
err() {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('with portal and with SSO', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
this.body = {
|
||||||
|
id: 1,
|
||||||
|
name: 'stanford',
|
||||||
|
enrolment_ad_html: 'v1 ad content',
|
||||||
|
is_university: true,
|
||||||
|
portal_slug: null,
|
||||||
|
sso_enabled: false
|
||||||
|
}
|
||||||
|
this.request.callsArgWith(1, null, { statusCode: 200 }, this.body)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should call v1 and create affiliation notifications', function(done) {
|
it('should call v1 and create affiliation notifications', function(done) {
|
||||||
const ip = '192.168.0.1'
|
const ip = '192.168.0.1'
|
||||||
return this.controller
|
this.controller.ipMatcherAffiliation(userId).create(ip, callback => {
|
||||||
.ipMatcherAffiliation(user_id)
|
|
||||||
.create(ip, callback => {
|
|
||||||
this.request.calledOnce.should.equal(true)
|
this.request.calledOnce.should.equal(true)
|
||||||
const expectedOpts = {
|
const expectedOpts = {
|
||||||
|
institutionId: this.body.id,
|
||||||
university_name: this.body.name,
|
university_name: this.body.name,
|
||||||
content: this.body.enrolment_ad_html
|
content: this.body.enrolment_ad_html,
|
||||||
|
ssoEnabled: false,
|
||||||
|
portalPath: undefined
|
||||||
}
|
}
|
||||||
this.handler.createNotification
|
this.handler.createNotification
|
||||||
.calledWith(
|
.calledWith(
|
||||||
user_id,
|
userId,
|
||||||
`ip-matched-affiliation-${this.body.id}`,
|
`ip-matched-affiliation-${this.body.id}`,
|
||||||
'notification_ip_matched_affiliation',
|
'notification_ip_matched_affiliation',
|
||||||
expectedOpts
|
expectedOpts
|
||||||
)
|
)
|
||||||
.should.equal(true)
|
.should.equal(true)
|
||||||
return done()
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe('without portal and without SSO', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
this.body = {
|
||||||
|
id: 1,
|
||||||
|
name: 'stanford',
|
||||||
|
enrolment_ad_html: 'v1 ad content',
|
||||||
|
is_university: true,
|
||||||
|
portal_slug: 'stanford',
|
||||||
|
sso_enabled: true
|
||||||
|
}
|
||||||
|
this.request.callsArgWith(1, null, { statusCode: 200 }, this.body)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should call v1 and create affiliation notifications', function(done) {
|
||||||
|
const ip = '192.168.0.1'
|
||||||
|
this.controller.ipMatcherAffiliation(userId).create(ip, callback => {
|
||||||
|
this.request.calledOnce.should.equal(true)
|
||||||
|
const expectedOpts = {
|
||||||
|
institutionId: this.body.id,
|
||||||
|
university_name: this.body.name,
|
||||||
|
content: this.body.enrolment_ad_html,
|
||||||
|
ssoEnabled: true,
|
||||||
|
portalPath: '/edu/stanford'
|
||||||
|
}
|
||||||
|
this.handler.createNotification
|
||||||
|
.calledWith(
|
||||||
|
userId,
|
||||||
|
`ip-matched-affiliation-${this.body.id}`,
|
||||||
|
'notification_ip_matched_affiliation',
|
||||||
|
expectedOpts
|
||||||
|
)
|
||||||
|
.should.equal(true)
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue