FEATURE: first pass at dinopark sign-up flow

Specs still need to be written.

https://github.com/mozilla/discourse/issues/186
This commit is contained in:
Leo McArdle 2019-04-05 13:44:49 +01:00
Родитель 02708a3278
Коммит c9e43eadf6
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 8262833620A64C3F
13 изменённых файлов: 205 добавлений и 3 удалений

Просмотреть файл

@ -0,0 +1,69 @@
import ModalFunctionality from "discourse/mixins/modal-functionality"
import showModal from "discourse/lib/show-modal"
import { on } from "ember-addons/ember-computed-decorators"
import { ajax } from "discourse/lib/ajax"
import { userPath } from "discourse/lib/url"
export default Ember.Controller.extend(ModalFunctionality, {
createAccount: Ember.inject.controller("create-account"),
showingConfirm: false,
tosChecked: false,
submitted: false,
@on("init")
fetchConfirmationValue() {
return ajax(userPath("hp.json")).then(json => {
this.setProperties({
accountPasswordConfirm: json.value,
accountChallenge: json.challenge
.split("")
.reverse()
.join("")
});
});
},
actions: {
normalSignup() {
const options = this.get("options")
const createAccountController = this.get("createAccount")
createAccountController.setProperties({
accountEmail: options.email,
accountUsername: options.username,
accountName: options.name,
authOptions: Ember.Object.create(options)
})
showModal("createAccount")
},
findProfile() {
this.set("showingConfirm", true)
},
confirm() {
this.set("submitted", true)
return ajax(userPath(), {
data: {
username: this.get("options").dinopark_profile.username,
email: this.get("options").email,
password_confirmation: this.get("accountPasswordConfirm"),
challenge: this.get("accountChallenge"),
dinopark_enabled: true
},
type: "POST"
}).then(result => {
if (result.success) {
var destination_url = this.get("options.destination_url")
window.location = destination_url ? destination_url : "/"
} else {
this.set("submitted", false)
this.flash(result.message || I18n.t("create_account.failed"), "error")
}
}, () => {
this.set("submitted", false)
this.flash(I18n.t("create_account.failed"), "error")
})
}
}
});

Просмотреть файл

@ -0,0 +1,27 @@
import { withPluginApi } from 'discourse/lib/plugin-api'
import showModal from "discourse/lib/show-modal"
export default {
name: 'dinopark-sign-up',
initialize () {
withPluginApi('0.8.30', api => {
api.modifyClass("controller:login", {
dinoparkSignUpController: Ember.inject.controller("dinopark-sign-up"),
authenticationComplete(options) {
if (options.dinopark_profile) {
const dinoParkSignUpController = this.get("dinoparkSignUpController")
dinoParkSignUpController.setProperties({
options: options
})
showModal("dinopark-sign-up")
} else {
this._super(options)
}
}
})
})
}
}

Просмотреть файл

@ -0,0 +1,39 @@
{{#d-modal-body class="dinopark-sign-up"}}
{{#if showingConfirm}}
<h1>{{i18n 'dinopark.sign_up.confirm_title'}}</h1>
<p>{{i18n 'dinopark.sign_up.confirm_description'}}</p>
{{else}}
<h1>{{i18n 'dinopark.sign_up.prompt_title'}}</h1>
<h4>{{i18n 'dinopark.sign_up.prompt_subtitle'}}</h4>
<p>{{i18n 'dinopark.sign_up.prompt_description'}}</p>
{{/if}}
<ul>
{{#if showingConfirm}}
<li>username: {{options.dinopark_profile.username}}</li>
<li>full name: {{options.dinopark_profile.full_name}}</li>
<li>pronouns: {{options.dinopark_profile.pronouns}}</li>
<li>fun title: {{options.dinopark_profile.fun_title}}</li>
<li>description: {{options.dinopark_profile.description}}</li>
<li>location: {{options.dinopark_profile.location}}</li>
{{else}}
<li>username</li>
<li>full name</li>
<li>pronouns</li>
<li>fun title</li>
<li>description</li>
<li>location</li>
{{/if}}
</ul>
{{input type="checkbox" id="tos-checkbox" checked=tosChecked}}
<label for="tos-checkbox">{{{i18n 'dinopark.sign_up.tos' tos_url=siteSettings.tos_url privacy_url=siteSettings.privacy_policy_url}}}</label>
{{/d-modal-body}}
<div class="modal-footer">
{{#conditional-loading-spinner condition=submitted size="small"}}
{{d-button label="dinopark.sign_up.cancel" action=(action "normalSignup")}}
{{#if showingConfirm}}
{{d-button label="dinopark.sign_up.confirm" class=(concat "btn-primary " (unless tosChecked "disabled")) disabled=(unless tosChecked true) action=(action "confirm")}}
{{else}}
{{d-button label="dinopark.sign_up.continue" class=(concat "btn-primary " (unless tosChecked "disabled")) disabled=(unless tosChecked true) action=(action "findProfile")}}
{{/if}}
{{/conditional-loading-spinner}}
</div>

Просмотреть файл

@ -1,3 +1,9 @@
.dinopark-sign-up {
label {
display: inline;
}
}
.user-preferences {
.dinopark-edit {

Просмотреть файл

@ -0,0 +1,4 @@
Auth::Result.prepend MozillaIAM::AuthResultExtensions
Auth::Result.class_eval do
attr_accessor :user_id
end

Просмотреть файл

@ -0,0 +1 @@
UsersController.prepend MozillaIAM::UsersControllerExtensions

Просмотреть файл

@ -15,6 +15,16 @@ en:
dinopark:
edit_short: "Edit"
edit_long: "Edit on people.mozilla.org"
sign_up:
tos: 'I agree to the <a href="%{privacy_url}">privacy policy</a> and <a href="%{tos_url}">terms of service</a>.'
prompt_title: "Discourse integrates with Mozilla Directory profiles"
prompt_subtitle: "Would you like to link your public profile fields?"
prompt_description: "You'll be able to review and confirm the information on the next screen."
confirm_title: "Review and confirm your profile information"
confirm_description: "The following public profile fields from your Mozilla Directory profile are ready to be linked."
cancel: "Not right now"
continue: "Yes, find and link my profile"
confirm: "Confirm and create linked account"
mozillians:
edit: "Edit on Mozillians"
mozilla_iam:

Просмотреть файл

@ -8,11 +8,13 @@ require_relative 'mozilla_iam/api/person'
require_relative 'mozilla_iam/api/person_v2'
require_relative 'mozilla_iam/api/management'
require_relative 'mozilla_iam/application_extensions'
require_relative 'mozilla_iam/auth_result_extensions'
require_relative 'mozilla_iam/authenticator'
require_relative 'mozilla_iam/jwks'
require_relative 'mozilla_iam/jwt'
require_relative 'mozilla_iam/profile'
require_relative 'mozilla_iam/omniauth_oauth2_extensions'
require_relative 'mozilla_iam/users_controller_extensions'
module MozillaIAM
end

Просмотреть файл

@ -33,6 +33,18 @@ module MozillaIAM
@location = process :location
end
def blank?
@raw.blank?
end
def to_hash
hash = {}
(instance_variables - [:@raw]).each do |var|
hash[var.to_s.delete_prefix("@")] = instance_variable_get(var)
end
hash
end
private
def process(name)

Просмотреть файл

@ -0,0 +1,16 @@
module MozillaIAM
module AuthResultExtensions
def to_client_hash
result = super
profile = MozillaIAM::API::PersonV2.new.profile(user_id)
unless profile.blank?
result.merge!({
dinopark_profile: profile.to_hash
})
end
result
end
end
end

Просмотреть файл

@ -34,7 +34,7 @@ module MozillaIAM
raise SecondaryEmailError.new(user, email)
end
result.name = payload['name']
uid = payload['sub']
result.user_id = uid = payload['sub']
result.extra_data = { uid: uid }
if user
@ -68,7 +68,9 @@ module MozillaIAM
def after_create_account(user, auth)
uid = auth[:extra_data][:uid]
Profile.new(user, uid).force_refresh
p = Profile.new(user, uid)
p.dinopark_enabled = true if auth[:dinopark_enabled]
p.force_refresh
end
def register_middleware(omniauth)

Просмотреть файл

@ -0,0 +1,14 @@
module MozillaIAM
module UsersControllerExtensions
def create
params.permit(:dinopark_enabled)
if dinopark_enabled = params[:dinopark_enabled]
session[:authentication][:dinopark_enabled] = dinopark_enabled
params[:username] = UserNameSuggester.find_available_username_based_on(params[:username])
end
super
end
end
end

Просмотреть файл

@ -1,6 +1,6 @@
# name: mozilla-iam
# about: A plugin to integrate Discourse with Mozilla's Identity and Access Management (IAM) system
# version: 1.2.0-alpha.10
# version: 1.2.0-alpha.11
# authors: Leo McArdle
# url: https://github.com/mozilla/discourse-mozilla-iam