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 portalPath = body.portal_slug
|
||||
? `/${body.is_university ? 'edu' : 'org'}/${body.portal_slug}`
|
||||
: undefined
|
||||
const messageOpts = {
|
||||
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(
|
||||
userId,
|
||||
|
|
|
@ -51,17 +51,40 @@ include ../../_mixins/saml
|
|||
span.sr-only #{translate("close")}
|
||||
.alert.alert-info(
|
||||
ng-switch-when="notification_ip_matched_affiliation"
|
||||
ng-if="notification.messageOpts.ssoEnabled"
|
||||
)
|
||||
.notification-body
|
||||
| It looks like you're at
|
||||
strong {{ notification.messageOpts.university_name }}! <br/>
|
||||
| Did you know that {{notification.messageOpts.university_name}} is providing
|
||||
strong free Overleaf Professional accounts
|
||||
| to everyone at {{notification.messageOpts.university_name}}? <br/>
|
||||
| Add an institutional email address to claim your account.
|
||||
| !{translate("looks_like_youre_at", {institutionName: '{{notification.messageOpts.university_name}}'}, ['strong'])}
|
||||
br
|
||||
| !{translate("you_can_now_log_in_sso", {}, ['strong'])}
|
||||
br
|
||||
| #{translate("link_institutional_email_get_started", {}, ['strong'])}
|
||||
a(
|
||||
ng-href="{{notification.messageOpts.portalPath || 'https://www.overleaf.com/learn/how-to/Institutional_Login'}}"
|
||||
) #{translate("find_out_more_nt")}
|
||||
.notification-action
|
||||
a.pull-right.btn.btn-sm.btn-info(href="/user/settings")
|
||||
| Add Affiliation
|
||||
a.pull-right.btn.btn-sm.btn-info(
|
||||
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
|
||||
button.btn-sm(ng-click="dismiss(notification)").close.pull-right
|
||||
span(aria-hidden="true") ×
|
||||
|
|
|
@ -1330,5 +1330,11 @@
|
|||
"github_is_premium": "GitHub sync is a premium feature",
|
||||
"remote_service_error": "The remote service produced an error",
|
||||
"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 { assert } = require('chai')
|
||||
require('chai').should()
|
||||
const sinon = require('sinon')
|
||||
const modulePath = require('path').join(
|
||||
|
@ -21,53 +7,100 @@ const modulePath = require('path').join(
|
|||
)
|
||||
|
||||
describe('NotificationsBuilder', function() {
|
||||
const user_id = '123nd3ijdks'
|
||||
const userId = '123nd3ijdks'
|
||||
|
||||
beforeEach(function() {
|
||||
this.handler = { createNotification: sinon.stub().callsArgWith(6) }
|
||||
|
||||
this.settings = { apis: { v1: { url: 'v1.url', user: '', pass: '' } } }
|
||||
this.body = { id: 1, name: 'stanford', enrolment_ad_html: 'v1 ad content' }
|
||||
const response = { statusCode: 200 }
|
||||
this.request = sinon
|
||||
.stub()
|
||||
.returns(this.stubResponse)
|
||||
.callsArgWith(1, null, response, this.body)
|
||||
return (this.controller = SandboxedModule.require(modulePath, {
|
||||
globals: {
|
||||
console: console
|
||||
},
|
||||
requires: {
|
||||
'./NotificationsHandler': this.handler,
|
||||
'settings-sharelatex': this.settings,
|
||||
request: this.request,
|
||||
'logger-sharelatex': {
|
||||
log() {},
|
||||
err() {}
|
||||
describe('ipMatcherAffiliation', function() {
|
||||
beforeEach(function() {
|
||||
this.handler = { createNotification: sinon.stub().callsArgWith(6) }
|
||||
this.settings = { apis: { v1: { url: 'v1.url', user: '', pass: '' } } }
|
||||
this.request = sinon.stub()
|
||||
this.controller = SandboxedModule.require(modulePath, {
|
||||
globals: {
|
||||
console: console
|
||||
},
|
||||
requires: {
|
||||
'./NotificationsHandler': this.handler,
|
||||
'settings-sharelatex': this.settings,
|
||||
request: this.request,
|
||||
'logger-sharelatex': {
|
||||
log() {},
|
||||
err() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
it('should call v1 and create affiliation notifications', function(done) {
|
||||
const ip = '192.168.0.1'
|
||||
return this.controller
|
||||
.ipMatcherAffiliation(user_id)
|
||||
.create(ip, callback => {
|
||||
this.request.calledOnce.should.equal(true)
|
||||
const expectedOpts = {
|
||||
university_name: this.body.name,
|
||||
content: this.body.enrolment_ad_html
|
||||
}
|
||||
this.handler.createNotification
|
||||
.calledWith(
|
||||
user_id,
|
||||
`ip-matched-affiliation-${this.body.id}`,
|
||||
'notification_ip_matched_affiliation',
|
||||
expectedOpts
|
||||
)
|
||||
.should.equal(true)
|
||||
return done()
|
||||
})
|
||||
})
|
||||
|
||||
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) {
|
||||
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: false,
|
||||
portalPath: undefined
|
||||
}
|
||||
this.handler.createNotification
|
||||
.calledWith(
|
||||
userId,
|
||||
`ip-matched-affiliation-${this.body.id}`,
|
||||
'notification_ip_matched_affiliation',
|
||||
expectedOpts
|
||||
)
|
||||
.should.equal(true)
|
||||
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