Published
Edited
Aug 29, 2022
Importers
2 stars
Insert cell
Insert cell
Insert cell
import {
onAuthStateChanged,
getAuth,
signOut,
signInWithCustomToken
} from "@tomlarkworthy/firebase-auth"
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
colors = ({
dark: "#4A44C4",
dark_darker: "#3933A3",
dark_darkest: "#2B277C",
light: "#FDF7E6",
light_darker: "#FBF0D1",
light_darkest: "#F9E8B8",
alt_light: "#9DE2BF",
alt_light_darker: "#75D6A5",
alt_light_darkest: "#4ECB8B",
alt_dark: "#E78AAE",
alt_darker: "#DE5E90",
alt_darkest: "#D53472",
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
container = (inner) => {
return view`<div class='es-frame'>${style()}${['...', inner()]}</div>`
}
Insert cell
Insert cell
Insert cell
container(() => htl.html`<div style="width: 400px">
<span class="e-btns">
${button({
action: "login",
label: "Comment signin",
icon: chatIcon
})}${button({
action: "copy",
label: "Copy",
icon: copyIcon
})}
</span>
<p class="e-info" style="font-size: 14px;">write a comment containing code <i>'dasdasdasdas'</i> in a comment<br>
⚠️ comment not found (try again?)</p>
</span>`)
Insert cell
content = ({
labels: {
copy: "Copy to clipboard",
login: "Login with comment",
logout: (auth) =>
`Logout <b>${auth.currentUser.uid.replace("observablehq|", "")}</b>`,
verify: "Login"
},
icons: {
copy: copyIcon,
login: chatIcon
}
})
Insert cell
expandContent = (auth, val) => (typeof val === "function" ? val(auth) : val)
Insert cell
viewof testScreen = screen({
info: "Please copy code",
actions: ["login", "verify"],
toggles: [
{
code: "profile_relmeauth",
label: html`[optional] scan for teams?`,
value: true,
caption: html`<details class='e-info' style="display: inline-block;font-size: 14px;"><summary>how does scanning work?</summary>
${md`From your Observablehq profile URL we look for weblinks to team profile URLs, and if those profile URLs also weblink to your profile URL we consider you to have admin access for that team. (related [relmeauth](https://observablehq.com/@endpointservices/auth#observable_features))`}
</details>`
}
]
})
Insert cell
testScreen
Insert cell
screen = ({ auth, info, actions = [], toggles = [] } = {}) =>
container(
() => view`<div>
<span class="e-btns">
${[
"actions",
actions.map((action) =>
button({
action,
label: expandContent(auth, content.labels[action]),
icon: content.icons[action]
})
)
]}
</span>
${info ? html`<p class="e-info" style="font-size: 14px;">${info}</p>` : ""}
${[
"...",
Object.fromEntries(
toggles.map((toggle) => {
return [
toggle.code,
view`<div>
<div>${[
"...",
stopPropagation(
Inputs.toggle({ label: toggle.label, value: toggle.value })
)
]}</div>
<div>${toggle.caption}</div>
</div>`
];
})
)
]}
</span>`
)
Insert cell
stopPropagation = _view => {
_view.addEventListener('input', evt => {
if (evt?.detail?.user === undefined) evt.stopPropagation();
});
return view`<span>${['...', _view]}`;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
prepare = async (
publicCode,
backend = "https://webcode.run/observablehq.com/@endpointservices/login-with-comment;prepare"
) => {
if (!publicCode) throw new Error("public code required");
const response = await fetch(`${backend}?code=${publicCode}`);
if (response.status !== 200)
throw new Error(`Err ${response.status}, ${await response.text()}`);
return await response.text();
}
Insert cell
prepareOK = suite.test("prepare returns 200", async () => {
const code = randomId(16);
expect(await prepare(code)).toBe("OK");
})
Insert cell
prepareCodeResuse = suite.test("prepare codes cannot be reused", async (done) => {
try {
const code = randomId(16);
await prepare(code);
await prepare(code);
} catch (err) {
done() // Test will only resolve it error thrown
}
})
Insert cell
Insert cell
Insert cell
Insert cell
html`<img width=300px src="${await FileAttachment(
"ezgif.com-gif-maker.webp"
).url()}"></img>`
Insert cell
Insert cell
Insert cell
Insert cell
mutable last_token = undefined;
Insert cell
Insert cell
Insert cell
teamScan = suite.test("team scan runs", async () => {
expect(await findObservablehqAccounts("tomlarkworthy")).toContain(
"tomlarkworthy"
);
})
Insert cell
verifyWithoutPrepare = suite.test(
"verify 401 when not prepared",
async (done) => {
try {
await verify({
notebookURL:
"https://observablehq.com/@endpointservices/login-with-comment",
privateCode: randomId()
});
} catch (err) {
expect(err.message).toBe("No code prepared");
done();
}
}
)
Insert cell
Insert cell
function checkIsURL(arg, name) {
try {
return new URL(arg).toString()
} catch (err) {
throw new Error(`${name || 'arg'} is not a URL`)
}
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more