Skip to content

Commit dbcf09d

Browse files
「Twitterログイン」を実装する #29
1 parent c104723 commit dbcf09d

File tree

9 files changed

+274
-60
lines changed

9 files changed

+274
-60
lines changed

.env.example

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,7 @@
77
DATABASE_URL="mysql://johndoe:randompassword@localhost:3306/mydb"
88

99
GMAIL_USER="iam.o.sin@gmail.com"
10-
GMAIL_PASS="google_app_password"
10+
GMAIL_PASS="google_app_password"
11+
12+
TWITTER_CLIENT_ID=""
13+
TWITTER_CLIENT_SECRET=""

.vscode/settings.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
"cSpell.words": [
33
"builtins",
44
"instanceof",
5+
"keypress",
56
"minlength",
67
"onfocus",
8+
"roboto",
79
"signin",
810
"sveltejs",
911
"sveltekit"

package-lock.json

Lines changed: 70 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
"type": "module",
3636
"dependencies": {
3737
"@prisma/client": "^4.5.0",
38-
"nodemailer": "^6.8.0"
38+
"nodemailer": "^6.8.0",
39+
"twitter-api-sdk": "^1.2.1",
40+
"twitter-api-v2": "^1.12.9"
3941
}
4042
}

src/lib/database.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1-
import prisma from '@prisma/client'
1+
import prisma, { type User } from '@prisma/client'
22

3-
export const db = new prisma.PrismaClient()
3+
enum Roles {
4+
admin = 'admin',
5+
user = 'user',
6+
}
7+
8+
export const db = new prisma.PrismaClient()
9+
10+
export async function findUser(email: string, can_register = true): Promise<User | undefined> {
11+
const user = await db.user.findUnique({ where: { email } })
12+
13+
if (user) return user
14+
if (!can_register) return undefined
15+
16+
try {
17+
return await db.user.create({
18+
data: {
19+
role: { connect: { name: Roles.user } },
20+
email,
21+
},
22+
})
23+
} catch (error) {
24+
console.error(error)
25+
return undefined
26+
}
27+
}

src/routes/login/+page.svelte

Lines changed: 70 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import { page } from '$app/stores'
44
import { onMount } from 'svelte'
55
6+
// const client = new Client("MY-BEARER-TOKEN");
7+
68
let first_element: HTMLInputElement
79
810
const redirect_url = $page.url.searchParams.get('redirect_url') ?? ''
@@ -35,6 +37,14 @@
3537
// post({ credential: response.credential })
3638
// }
3739
40+
function signinTwitter(): void {
41+
const form_element = document.getElementById('signin_twitter')
42+
43+
if (form_element instanceof HTMLFormElement) {
44+
form_element.submit()
45+
}
46+
}
47+
3848
onMount(() => {
3949
document.onfocus = (event): void => {
4050
if (event.target instanceof HTMLInputElement) event.target.select()
@@ -69,21 +79,64 @@
6979
data-auto_prompt="true"
7080
data-auto_select="true"
7181
/>
72-
<div
73-
class="g_id_signin"
74-
data-width="240"
75-
data-type="standard"
76-
data-size="large"
77-
data-theme="outline"
78-
data-text="sign_in_with"
79-
data-shape="rectangular"
80-
data-logo_alignment="left"
81-
/>
82-
83-
<!-- <div id="buttonDiv" style="max-width:400" /> -->
84-
<br />
85-
<form method="POST" action="/pin_code?/login&redirect_url={encoded_redirect_url}">
86-
<input type="email" name="email" placeholder="Email" required bind:this={first_element} />
8782

88-
<button type="submit">Log in</button>
89-
</form>
83+
<div class="flex_column">
84+
<div
85+
class="g_id_signin"
86+
data-width="240"
87+
data-type="standard"
88+
data-size="large"
89+
data-theme="outline"
90+
data-text="sign_in_with"
91+
data-shape="rectangular"
92+
data-logo_alignment="left"
93+
/>
94+
95+
<form method="POST" action="/signin_twitter" id="signin_twitter">
96+
<div class="signin_twitter" on:click={signinTwitter} on:keypress={signinTwitter}>
97+
<div class="flex_row_twitter roboto">
98+
<img src="./twitter_social_icon_circle_blue.svg" alt="" width="20px" />
99+
<div>Twitter でログイン</div>
100+
</div>
101+
</div>
102+
</form>
103+
104+
<!-- <div id="buttonDiv" style="max-width:400" /> -->
105+
<form method="POST" action="/pin_code?/login&redirect_url={encoded_redirect_url}">
106+
<input type="email" name="email" placeholder="Email" required bind:this={first_element} />
107+
108+
<button type="submit">Log in</button>
109+
</form>
110+
</div>
111+
112+
<style>
113+
.flex_column {
114+
display: flex;
115+
flex-direction: column;
116+
gap: 12px;
117+
}
118+
119+
.signin_twitter {
120+
width: 238px;
121+
height: 40px;
122+
border: 1px solid #dadce0;
123+
border-radius: 4px;
124+
cursor: pointer;
125+
}
126+
127+
.flex_row_twitter {
128+
height: 40px;
129+
display: flex;
130+
flex-direction: row;
131+
gap: 8px;
132+
align-items: center;
133+
padding: 0 8px;
134+
}
135+
136+
.roboto {
137+
color: #3c4043;
138+
font-family: sans-serif;
139+
font-weight: 80;
140+
font-size: 12px;
141+
}
142+
</style>

0 commit comments

Comments
 (0)