Skip to content

Commit

Permalink
Merge pull request #86 from jeremykenedy/provider-updates
Browse files Browse the repository at this point in the history
Provider updates
  • Loading branch information
jeremykenedy authored Dec 16, 2022
2 parents e844c31 + dbf70e8 commit 7f6108f
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 75 deletions.
4 changes: 3 additions & 1 deletion app/Http/Controllers/Auth/SocialiteController.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ public function getSocialRedirect(string $provider, Request $request)
}

return response()->json([
'url' => Socialite::driver($provider)->stateless()->with(['state' => $state])->redirect()->getTargetUrl(),
'url' => Socialite::driver($provider)->stateless()->with([
'state' => $state,
])->redirect()->getTargetUrl(),
]);
}

Expand Down
5 changes: 5 additions & 0 deletions app/Traits/SocialiteProvidersTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ protected function loginsList()
protected function findOrCreateUser(string $provider, SocialiteUser $user, string $state = null): array
{
$existingUser = null;
$token = null;

if ($state && $state != config('app.key')) {
$token = PersonalAccessToken::findToken($state);
Expand All @@ -458,6 +459,10 @@ protected function findOrCreateUser(string $provider, SocialiteUser $user, strin
$existingUser = User::whereEmail($user->getEmail())->first();
}

if (! $existingUser) {
$existingUser = auth('sanctum')->user();
}

$oauthProvider = SocialiteProvider::where('provider', $provider)
->where('provider_user_id', $user->getId())
->first();
Expand Down
64 changes: 6 additions & 58 deletions resources/js/components/account/AccountAuthentication.vue
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,11 @@ import VueAxios from 'vue-axios';
import { mapState, mapActions, mapGetters } from 'vuex';
import { track } from '@services/analytics';
import { PowerIcon } from '@heroicons/vue/24/outline';
import { parseDisplayDate, capitalizeFirstLetter } from '@services/common';
import {
parseDisplayDate,
capitalizeFirstLetter,
providerIcon,
} from '@services/common';
export default {
name: 'AccountAuthentication',
Expand Down Expand Up @@ -179,70 +183,14 @@ export default {
track,
parseDisplayDate,
capitalizeFirstLetter,
providerIcon,
providerConnected(provider, user) {
const found = user.providers.find((p) => p.provider == provider);
if (found) {
return found;
}
return false;
},
providerIcon(provider) {
if (provider.toLowerCase() == 'apple') {
return 'fa-brands fa-apple text-gray-800 dark:text-gray-200';
}
if (provider.toLowerCase() == 'twitter') {
return 'fa-brands fa-twitter text-blue-300 dark:text-blue-200';
}
if (provider.toLowerCase() == 'google') {
return 'fa-brands fa-google text-red-500 dark:text-gray-200';
}
if (provider.toLowerCase() == 'microsoft') {
return 'fa-brands fa-microsoft text-blue-300 dark:text-gray-200';
}
if (provider.toLowerCase() == 'tiktok') {
return 'fa-brands fa-tiktok text-pink-600 dark:text-gray-200';
}
if (provider.toLowerCase() == 'youtube') {
return 'fa-brands fa-youtube text-red-600 dark:text-gray-200';
}
if (provider.toLowerCase() == 'instagram') {
return 'fa-brands fa-instagram text-gray-800 dark:text-gray-200';
}
if (provider.toLowerCase() == 'facebook') {
return 'fa-brands fa-facebook text-blue-600 dark:text-gray-200';
}
if (provider.toLowerCase() == 'github') {
return 'fa-brands fa-github text-gray-700 dark:text-gray-200';
}
if (provider.toLowerCase() == 'twitch') {
return 'fa-brands fa-twitch text-blue-300 dark:text-gray-200';
}
if (provider.toLowerCase() == 'linkedin') {
return 'fa-brands fa-linkedin text-blue-900 dark:text-gray-200';
}
if (provider.toLowerCase() == 'zoho') {
return 'fas fa-z text-yellow-500 dark:text-gray-200';
}
if (provider.toLowerCase() == 'stackexchange') {
return 'fa-brands fa-stack-exchange text-blue-400 dark:text-gray-200';
}
if (provider.toLowerCase() == 'gitlab') {
return 'fa-brands fa-square-gitlab text-orange-400 dark:text-gray-200';
}
if (provider.toLowerCase() == 'reddit') {
return 'fa-brands fa-square-reddit text-orange-700 dark:text-gray-200';
}
if (provider.toLowerCase() == 'snapchat') {
return 'fa-brands fa-square-snapchat text-yellow-400 dark:text-gray-200';
}
if (provider.toLowerCase() == 'meetup') {
return 'fa-brands fa-meetup text-red-400 dark:text-gray-200';
}
// NEW_PROVIDER_PLUG :: Put New Provider HERE
return 'fa-solid fa-plug-circle-check text-gray-600 dark:text-gray-200';
},
triggerRevoke(provider) {
const self = this;
const title = '<strong>Revoke ';
Expand Down
2 changes: 1 addition & 1 deletion resources/js/router/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export default [
path: '/settings',
component: Settings,
redirect: {
name: 'profile',
name: 'account',
},
name: 'settings',
meta: {
Expand Down
72 changes: 72 additions & 0 deletions resources/js/services/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,75 @@ export function capitalizeFirstLetter(str) {

return str.slice(0, 2).toUpperCase() + str.slice(2);
}

export function greeting() {
const date = new Date();
const currentTime = date.getHours();
let greeting;
if (currentTime >= 0 && currentTime <= 12) {
greeting = 'Good Morning';
} else if (currentTime > 12 && currentTime <= 18) {
greeting = 'Good Afternoon';
} else {
greeting = 'Good Evening';
}
return greeting;
}

export function providerIcon(provider = null) {
if (provider.toLowerCase() == 'apple') {
return 'fa-brands fa-apple text-gray-800 dark:text-gray-200';
}
if (provider.toLowerCase() == 'twitter') {
return 'fa-brands fa-twitter text-blue-300 dark:text-blue-200';
}
if (provider.toLowerCase() == 'google') {
return 'fa-brands fa-google text-red-500 dark:text-gray-200';
}
if (provider.toLowerCase() == 'microsoft') {
return 'fa-brands fa-microsoft text-blue-300 dark:text-gray-200';
}
if (provider.toLowerCase() == 'tiktok') {
return 'fa-brands fa-tiktok text-pink-600 dark:text-gray-200';
}
if (provider.toLowerCase() == 'youtube') {
return 'fa-brands fa-youtube text-red-600 dark:text-gray-200';
}
if (provider.toLowerCase() == 'instagram') {
return 'fa-brands fa-instagram text-gray-800 dark:text-gray-200';
}
if (provider.toLowerCase() == 'facebook') {
return 'fa-brands fa-facebook text-blue-600 dark:text-gray-200';
}
if (provider.toLowerCase() == 'github') {
return 'fa-brands fa-github text-gray-700 dark:text-gray-200';
}
if (provider.toLowerCase() == 'twitch') {
return 'fa-brands fa-twitch text-blue-300 dark:text-gray-200';
}
if (provider.toLowerCase() == 'linkedin') {
return 'fa-brands fa-linkedin text-blue-900 dark:text-gray-200';
}
if (provider.toLowerCase() == 'zoho') {
return 'fas fa-z text-yellow-500 dark:text-gray-200';
}
if (provider.toLowerCase() == 'stackexchange') {
return 'fa-brands fa-stack-exchange text-blue-400 dark:text-gray-200';
}
if (provider.toLowerCase() == 'gitlab') {
return 'fa-brands fa-square-gitlab text-orange-400 dark:text-gray-200';
}
if (provider.toLowerCase() == 'reddit') {
return 'fa-brands fa-square-reddit text-orange-700 dark:text-gray-200';
}
if (provider.toLowerCase() == 'snapchat') {
return 'fa-brands fa-square-snapchat text-yellow-400 dark:text-gray-200';
}
if (provider.toLowerCase() == 'meetup') {
return 'fa-brands fa-meetup text-red-400 dark:text-gray-200';
}

// NEW_PROVIDER_PLUG :: Put New Provider HERE

return 'fa-solid fa-plug-circle-check text-gray-600 dark:text-gray-200';
}
127 changes: 114 additions & 13 deletions resources/js/views/pages/Dashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,84 @@
class="rounded bg-white p-4 dark:bg-slate-800 dark:text-gray-300"
>
<h1 class="mt-4 mb-4 text-center text-2xl">
{{ greeting }},
{{ greeting() }},
{{ user && user.name ? user.name : 'Registered User' }}!
</h1>
<div v-if="roles" class="mb-6 text-center">
<hr class="mx-auto mb-3 w-10" />
<h2 class="mb-5">Your Roles</h2>
<RolesBadges :roles="roles" />
</div>

<div v-if="socialLoginsEnabled">
<router-link
v-tippy="'Go to application service providers'"
:to="{ name: 'account' }"
>
<div
v-if="user.providers.length == 0"
class="rounded-lg bg-slate-100 p-10 text-center text-gray-600 transition duration-200 ease-in-out hover:bg-slate-200 hover:text-gray-800 dark:bg-slate-900 hover:dark:bg-slate-700 hover:dark:text-white"
>
<div>
<PowerIcon class="ml-auto mr-auto mb-4 h-12 w-12" />
</div>
<h2 class="text-lg">
No applications are integrated into your account.
</h2>
</div>
<div v-if="user.providers.length > 0">
<div
class="grid grid-cols-2 gap-4 rounded-lg text-center font-mono text-sm font-bold leading-6 text-white sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5"
>
<div
v-for="(provider, index) in enabledProviders"
:key="provider + '_' + index"
class="mb-1 w-full rounded-lg border border-gray-200 bg-white shadow-md hover:bg-gray-50 dark:border-gray-900 dark:bg-gray-900 hover:dark:bg-slate-700"
>
<div
class="flex flex-col items-center pt-4 pb-4 pl-2 pr-2"
>
<span
class="fa-4x mb-2"
:class="providerIcon(provider.provider)"
/>
<h5
class="mb-0 text-lg font-extrabold capitalize text-gray-900 dark:text-white"
>
{{ provider.provider }}
</h5>
<div
v-if="provider.created_at"
class="mb-1 mb-3 text-gray-600 dark:text-gray-400"
style="line-height: 1.2; font-size: 0.6em"
>
<span
class="font-bold uppercase text-gray-700 dark:text-gray-200"
>
<span class="far fa-clock" /> First Used:
</span>
<br />
{{ parseDisplayDate(provider.created_at) }}
</div>
<div
v-if="provider.updated_at"
class="mb-0 text-gray-600 dark:text-gray-400"
style="line-height: 1.2; font-size: 0.6em"
>
<span
class="font-bold uppercase text-gray-700 dark:text-gray-200"
>
<span class="far fa-clock" /> Last Used:
</span>
<br />
{{ parseDisplayDate(provider.updated_at) }}
</div>
</div>
</div>
</div>
</div>
</router-link>
</div>
</div>
</div>
</div>
Expand All @@ -28,36 +98,67 @@
</template>

<script>
import { mapGetters } from 'vuex';
import { mapState, mapActions, mapGetters } from 'vuex';
import RolesBadges from '@components/roles/RolesBadges.vue';
import { greeting, providerIcon, parseDisplayDate } from '@services/common';
import { PowerIcon } from '@heroicons/vue/24/outline';
export default {
name: 'Dashboard',
components: {
RolesBadges,
PowerIcon,
},
data() {
return {};
},
computed: {
...mapState('auth', {
user: (state) => state.user,
}),
...mapGetters({
authenticated: 'auth/authenticated',
user: 'auth/user',
roles: 'auth/roles',
logins: 'auth/logins',
}),
greeting() {
const date = new Date();
const currentTime = date.getHours();
let greeting;
if (currentTime >= 0 && currentTime <= 12) {
greeting = 'Good Morning';
} else if (currentTime > 12 && currentTime <= 18) {
greeting = 'Good Afternoon';
} else {
greeting = 'Good Evening';
socialLoginsEnabled() {
if (Object.values(this.logins).find((v) => v == '1')) {
return true;
}
return false;
},
allowedProviders() {
const providers = [];
for (const key in this.logins) {
if (this.logins[key] != false && this.logins[key] != '0') {
providers.push(key);
}
}
return greeting;
return providers.sort();
},
enabledProviders() {
const providers = [];
this.user.providers.forEach((provider, index) => {
const found = this.allowedProviders.find((p) => p == provider.provider);
if (found) {
providers.push(provider);
}
});
return providers;
},
disabledProviders() {
let providers = this.allowedProviders;
this.user.providers.forEach((provider, index) => {
providers = providers.filter((p) => p != provider.provider);
});
return providers;
},
},
methods: {
greeting,
providerIcon,
parseDisplayDate,
},
};
</script>
2 changes: 0 additions & 2 deletions vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ const fs = require('node:fs');

export default ({ mode }) => {
process.env = { ...process.env, ...loadEnv(mode, process.cwd()) };

var SentryPlugin = null;

if (process.env.VITE_SENTRY_IO_ENABLED) {
SentryPlugin = sentryVitePlugin({
include: '.',
Expand Down

0 comments on commit 7f6108f

Please sign in to comment.