132 lines
3.7 KiB
JavaScript
132 lines
3.7 KiB
JavaScript
(function (global, factory) {
|
|
typeof exports === "object" && typeof module !== "undefined"
|
|
? factory()
|
|
: typeof define === "function" && define.amd
|
|
? define(factory)
|
|
: (global.HamsooID = factory())
|
|
})(this, function () {
|
|
"use strict"
|
|
|
|
const defaults = {
|
|
client_id: "",
|
|
redirect_uri: "",
|
|
scope: "openid profile email",
|
|
response_mode: "redirect",
|
|
onSuccess: () => {},
|
|
onError: () => {},
|
|
}
|
|
|
|
let config = { ...defaults }
|
|
|
|
function renderButton(container, customHtml = null) {
|
|
const btn = document.createElement("button")
|
|
btn.type = "button"
|
|
btn.className = "hamsoo-signin-button"
|
|
btn.innerHTML = customHtml || /*html*/ `<span style="vertical-align:middle;">Sign in with Hamsoo</span><svg width="16" height="16" viewBox="0 0 24 24" style="vertical-align:middle; margin-left:4px; fill:#fff;"><path d="M12 3l5 9-5 9H5V7h7zm0-5l5 5L5 12h10l-5 5V2z"/></svg>`
|
|
btn.style.cssText = [
|
|
"width:100%",
|
|
"margin-top:20px",
|
|
"padding:12px",
|
|
"background:#2f6df6",
|
|
"color:#fff",
|
|
"border:none",
|
|
"border-radius:10px",
|
|
"font-size:15px",
|
|
"cursor:pointer",
|
|
"font-family:-apple-system,BlinkMacSystem,Segoe UI,Tahoma,sans-serif",
|
|
].join(";")
|
|
btn.addEventListener("click", handleClick)
|
|
container.innerHTML = ""
|
|
container.appendChild(btn)
|
|
}
|
|
|
|
function handleClick() {
|
|
const params = new URLSearchParams({
|
|
client_id: config.client_id,
|
|
response_type: "code",
|
|
redirect_uri: config.redirect_uri,
|
|
scope: config.scope,
|
|
response_mode: config.response_mode,
|
|
state: crypto.randomUUID(),
|
|
code_challenge_method: "S256",
|
|
})
|
|
|
|
let url = "/oauth/authorize?" + params.toString()
|
|
if (config.response_mode === "web_message") {
|
|
url += "&prompt=login"
|
|
}
|
|
|
|
const isPopup = config.response_mode === "web_message"
|
|
let width = 600,
|
|
height = 800
|
|
|
|
if (isPopup) {
|
|
width = 600
|
|
height = 800
|
|
const left = (screen.width - width) / 2
|
|
const top = (screen.height - height) / 2
|
|
const win = window.open(
|
|
url,
|
|
"HamsooSignIn",
|
|
`width=${width},height=${height},left=${left},top=${top},menubar=no,toolbar=no,status=no`
|
|
)
|
|
if (win) {
|
|
listenForMessage(win)
|
|
} else {
|
|
config.onError(new Error("Popup blocked"))
|
|
}
|
|
} else {
|
|
window.location.href = url
|
|
}
|
|
}
|
|
|
|
function listenForMessage(win) {
|
|
const listener = (event) => {
|
|
if (
|
|
event.data &&
|
|
event.data.type === "authorization_response" &&
|
|
event.origin.startsWith("http://") &&
|
|
event.origin.includes("hamsoo.me")
|
|
) {
|
|
const { code, state } = event.data
|
|
if (code) {
|
|
unlistenForMessage()
|
|
config.onSuccess({ code, state })
|
|
} else if (event.data.error) {
|
|
unlistenForMessage()
|
|
config.onError(new Error(event.data.error))
|
|
}
|
|
}
|
|
}
|
|
|
|
function unlistenForMessage() {
|
|
window.removeEventListener("message", listener)
|
|
}
|
|
|
|
window.addEventListener("message", listener)
|
|
|
|
// Auto-close after 10s if no message received
|
|
const timer = setTimeout(() => {
|
|
unlistenForMessage()
|
|
config.onError(new Error("Authorization timed out"))
|
|
win.close()
|
|
}, 10000)
|
|
}
|
|
|
|
return {
|
|
init: (options) => {
|
|
config = { ...defaults, ...options }
|
|
const container = document.getElementById("hamsoo-signin-root") || document.body
|
|
renderButton(container)
|
|
},
|
|
|
|
render: (customHtml) => {
|
|
const container = document.getElementById("hamsoo-signin-root") || document.body
|
|
renderButton(container, customHtml)
|
|
},
|
|
|
|
setConfig: (options) => {
|
|
config = { ...config, ...options }
|
|
},
|
|
}
|
|
}) |