Skip to content

Commit

Permalink
Coloca token no secure store + privacidade
Browse files Browse the repository at this point in the history
  • Loading branch information
migeyel committed May 16, 2023
1 parent e3c1524 commit acd3d3c
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 20 deletions.
66 changes: 66 additions & 0 deletions PRIVACY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
Política de privacidade
=======================

### 1\. Do direito à privacidade

A Lei 13709/2018 - Lei Geral de Proteção de Dados (LGPD) estabelece como fundamento o respeito à privacidade. A privacidade é um direito conferido a todo indivíduo e consiste na habilidade que este tem de controlar a exposição de informações sobre sua vida pessoal, sua intimidade, bem como a disponibilidade de dados sobre si mesmo, de retificar, ratificar ou apagar estes e de proteger a confidencialidade de suas comunicações, seu domicílio, sua imagem, honra e reputação perante terceiros. Desse modo, a presente Política de Privacidade (“Política”) tem o propósito de comunicar de forma simples quais tipos de dados pessoais serão coletados, quando, de que forma e para quais finalidades serão utilizados.

Quando o usuário aceita esta Política de Privacidade, confere sua livre e expressa concordância com os termos aqui estipulados, diretamente ou por meio de seu responsável legal, que deve estar ciente também das regras aqui estabelecidas

Este documento tem a finalidade de estabelecer a Política de Privacidade e os Termos de Uso.

### 2. Do propósito da coleta, uso e armazenamento das informações do usuário

A coleta, uso e armazenamento das suas informações têm como propósitos:

* promover os serviços da Universidade, além de informar sobre novidades, conteúdos e demais informações relevantes;
* armazenar preferências de usuário com relação a interface do aplicativo;
* facilitar a organização do estudante durante o semestre letivo.
* oferecer uma função opcional de automatização da sincronização do saldo do restaurante universitário, mediante a utilização do RA/CPF e senha do SIGA. Quando habilitada, essas informações serão armazenadas de forma segura no secure storage, a fim de possibilitar a sincronização automática do saldo do restaurante universitário no UFSCar Planner.

Quando você usa o aplicativo, alguns dos dados inseridos são salvos localmente no seu dispositivo, enquanto outros não serão salvos. Logo, os dados inseridos no aplicativo são exclusivamente de seu acesso.

### 3. Sobre os dados tratados

| Dados Coletados | Dado Obrigatório | Dado Armazenado | Finalidade | Bases Legais |
| --- | --- | --- | --- | --- |
| Campus | Sim | Sim | Identificação necessária à operação do sistema e aos serviços prestados por meio dele. | O tratamento dos dados é amparado nos parágrafos I e III, art.7 da Lei Nº 13.709, DE 14 DE AGOSTO DE 2018 que diz:Art. 7º O tratamento de dados pessoais somente poderá ser realizado nas seguintes hipóteses:I - mediante o fornecimento de consentimento pelo titular;...III - pela administração pública, para o tratamento e uso compartilhado de dados necessários à execução de políticas públicas previstas em leis e regulamentos ou respaldadas em contratos, convênios ou instrumentos congêneres, observadas as disposições do Capítulo IV desta Lei; |
| CPF | Não | Opcional\* (armazenado no secure storage apenas caso o usuário aceite e ative a função de sincronização automatica de saldo) | Dado necessário para a automatização da sincronização do saldo do restaurante universitário, quando habilitada pelo usuário. Dado necessário a integração do UFSCar Planner ao Sistema de Gestão Acadêmica. | Consentimento do titular\*\* |
| RA | Não | Opcional\* (armazenado no secure storage apenas caso o usuário aceite e ative a função de sincronização automatica de saldo) | Dado necessário para a automatização da sincronização do saldo do restaurante universitário, quando habilitada pelo usuário.Dado necessário a integração do UFSCar Planner ao Sistema de Gestão Acadêmica. | Consentimento do titular\*\* |
| Senha do Sistema SIGA | Não | Opcional\* (armazenado no secure storage apenas caso o usuário aceite e ative a função de sincronização automatica de saldo) | Dado necessário para a automatização da sincronização do saldo do restaurante universitário, quando habilitada pelo usuário. Dado necessário a integração do UFSCar Planner ao Sistema de Gestão Acadêmica. | Consentimento do titular\*\* |
| Fuso-horário | Não | Não | Aprimorar a interação do usuário com o sistema |
| Apelido | Sim | Sim | Tornar o uso do sistema mais acolhedor ao usuário. |
| Notas | Não | Sim | Sendo uma plataforma de organização universitária, o tratamento desse tipo de dado faz parte dos serviços prestados por meio do UFSCar Planner. |
| Frequências | Não | Sim | Sendo uma plataforma de organização universitária, o tratamento desse tipo de dado faz parte dos serviços prestados por meio do UFSCar Planner. |
| Eventos | Não | Sim | Sendo uma plataforma de organização universitária, o tratamento desse tipo de dado faz parte dos serviços prestados por meio do UFSCar Planner. |
| Saldo atual da _carteirinha do restaurante universitário_ | Não | Sim (armazenado no secure storage) | Sendo uma plataforma de organização universitária, o tratamento desse tipo de dado faz parte dos serviços prestados por meio do UFSCar Planner. |
| Valor padrão da refeição do restaurante universitário | Não | Sim | Sendo uma plataforma de organização universitária, o tratamento desse tipo de dado faz parte dos serviços prestados por meio do UFSCar Planner. |
| Disciplinas a que o usuário está vinculado | Não | Sim | Sendo uma plataforma de organização universitária, o tratamento desse tipo de dado faz parte dos serviços prestados por meio do UFSCar Planner. |

\* O fornecimento do CPF, RA e Senha do sistema SIGA é opcional e requer o consentimento do titular.

\*\* O tratamento do CPF, RA e Senha do sistema SIGA para a automatização da sincronização do saldo do restaurante universitário é realizado com base no consentimento do titular. O usuário pode optar por habilitar essa função no UFSCar Planner e fornecer seu CPF, RA e Senha do SIGA, cientes de que essas informações serão armazenadas de forma segura no secure storage e utilizadas exclusivamente para a finalidade de automatização da sincronização do saldo do restaurante universitário.

### 4. Gestão e segurança das informações do usuário

Os dados sensíveis, como CPF, RA e Senha do SIGA, fornecidos pelo usuário para a automatização da sincronização do saldo do restaurante universitário serão armazenados de forma segura no secure storage.

Os dados sobre os deferimentos do usuário serão obtidos após a verificação de seu vínculo com a Instituição, utilizando os dados relacionados a esta inseridos pelo usuário voluntariamente.

As informações são protegidas com padrões de segurança e confidencialidade, para fornecer aos usuários um ambiente seguro e confiável através do uso de criptografia, certificações digitais e acessos controlados.

### 5\. Cookies Utilizados

O aplicativo não utiliza cookies.

### 6\. Compartilhamento

Os dados coletados e enviados para o Google Analytics são anonimizados, fora isto o aplicativo não compartilha dados com terceiros.

### 7. Disposições Finais

As disposições constantes desta Política de Privacidade estão sujeitas à melhoria e ao aprimoramento contínuo e podem ser atualizadas ou modificadas a qualquer momento, de forma unilateral ou em razão de lei, cabendo ao usuário, ou a seu responsável legal, caso seja menor de idade, o dever de ciência de seu teor no momento do acesso aos sites e plataformas de sistemas da instituição. É recomendado que a leitura periódica desta Política seja realizada para fins de atualização e conhecimento de direitos e obrigações.

### 8. Contato

Caso tenha alguma dúvida ou sugestão sobre esta Política de Privacidade, não hesite em nos contatar através do email [email protected].
96 changes: 91 additions & 5 deletions helpers/balance.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,36 @@
import { Dispatch } from "redux";
import { UpdateUserAction, updateUser } from "../redux/actions/userActions";
import { User } from "../redux/types/user";
import * as SecureStore from "expo-secure-store";

/**
* Define o token no SecureStore.
* @param token - O token para definir.
* @returns `true` sse a operação foi um sucesso.
*/
async function setRuAuthToken(token: string): Promise<boolean> {
if (!await SecureStore.isAvailableAsync()) { return false; }
await SecureStore.setItemAsync("ufscarplanner.user.ruauth", token);
return true;
}

/**
* Apaga o token no SecureStore.
*/
async function deleteRuAuthToken(): Promise<void> {
if (await SecureStore.isAvailableAsync()) {
SecureStore.deleteItemAsync("ufscarplanner.user.ruauth");
}
}

/**
* Extrai o token do SecureStore.
* @returns O token extraído, ou nulo se não existir.
*/
async function getRuAuthToken(): Promise<string | null> {
if (!await SecureStore.isAvailableAsync()) { return null; }
return await SecureStore.getItemAsync("ufscarplanner.user.ruauth");
}

const URL = "https://sistemas.ufscar.br/sagui-api/integracoes/pwacesso/consultar-saldo";

Expand All @@ -23,13 +55,47 @@ export function isBalanceSyncEnabled(user: User): boolean {
}

/**
* Tenta obter o saldo pela API.
* @param user - O usuário para autenticar a API.
* Altera o estado da sincronização.
* @param user - O objeto de usuário para submeter ao estado.
* @param token - O token de autorização da API.
* @param dispatch - A função de dispatch do estado.
*/
export async function enableBalanceSync(
user: User,
token: string,
dispatch: Dispatch<UpdateUserAction>,
) {
if (await setRuAuthToken(token)) {
dispatch(updateUser({ ...user, balanceSyncToken: "" }));
} else {
dispatch(updateUser({ ...user, balanceSyncToken: token }));
}
}

/**
* Desabilita a sincronização.
* @param user - O objeto de usuário para submeter ao estado.
* @param dispatch - A função de dispatch do estado.
*/
export async function disableBalanceSync(
user: User,
dispatch: Dispatch<UpdateUserAction>,
) {
await deleteRuAuthToken();
const newUser = { ...user };
delete newUser.balanceSyncToken;
dispatch(updateUser(newUser));
}

/**
* Tenta obter o saldo pela API usando o token diretamente.
* @param token - O token para autenticar.
* @returns O saldo, ou uma string de erro em caso de erro.
*/
export async function tryGetBalance(user: User): Promise<number | BalanceErr> {
if (!isBalanceSyncEnabled(user)) { return BalanceErr.DISABLED; }
const headers = { Authorization: "Basic " + user.balanceSyncToken };
export async function tryGetBalanceWithToken(
token: string,
): Promise<number | BalanceErr> {
const headers = { Authorization: "Basic " + token };
const response = await fetch(URL, { headers });
if (response.status == 200) {
try {
Expand All @@ -48,3 +114,23 @@ export async function tryGetBalance(user: User): Promise<number | BalanceErr> {
return BalanceErr.UNKNOWN;
}
}

/**
* Tenta obter o saldo pela API, usando o SecureStore caso necessário.
* @param user - O usuário para autenticar a API.
* @returns O saldo, ou uma string de erro em caso de erro.
*/
export async function tryGetBalance(user: User): Promise<number | BalanceErr> {
if (!isBalanceSyncEnabled(user)) { return BalanceErr.DISABLED; }
if (user.balanceSyncToken == "") {
const token = await getRuAuthToken();
if (token === null) {
// O token sumiu do SecureStore!
return BalanceErr.UNKNOWN;
} else {
return await tryGetBalanceWithToken(token);
}
} else {
return tryGetBalanceWithToken(user.balanceSyncToken as string);
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"expo-device": "^5.2.1",
"expo-linear-gradient": "~12.1.2",
"expo-notifications": "~0.18.1",
"expo-secure-store": "^12.1.1",
"expo-status-bar": "~1.4.4",
"expo-updates": "^0.16.4",
"lodash.debounce": "^4.0.8",
Expand Down
3 changes: 3 additions & 0 deletions redux/types/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ export type User = {
/**
* O token de autorização Basic do usuário para sincronização do RU. Não é
* definido se a sincronização estiver desativada.
*
* Se a sincronização estiver ativada e o token for amazenado no armazenamento
* seguro, o valor deste campo é igual à string vazia.
*/
balanceSyncToken?: string,
}
Expand Down
9 changes: 3 additions & 6 deletions screens/Dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ import ScrollView from "./../components/ScrollView";
import Progress from "../components/Progress";
import TextTicker from "react-native-text-ticker";
import { SIGA } from "../helpers/helper";
import { isBalanceSyncEnabled } from "../helpers/balance";
import { disableBalanceSync, isBalanceSyncEnabled } from "../helpers/balance";
import { Button, Portal, Dialog } from "react-native-paper";
import { updateUser } from "../redux/actions/userActions";
import Toast from "react-native-toast-message";

export default function Dashboard() {
Expand Down Expand Up @@ -277,11 +276,9 @@ export default function Dashboard() {
Cancelar
</Button>
<Button
onPress={() => {
onPress={async() => {
setOpenSyncDialog(false);
const rest = { ...user };
delete rest.balanceSyncToken;
dispatch(updateUser(rest));
await disableBalanceSync(user, dispatch);
Toast.show({
text1: "A sincronização de saldo foi desativada.",
});
Expand Down
2 changes: 1 addition & 1 deletion screens/Welcome.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ function ScreenZero({ setPage }) {
/ Termos de uso.
</Text>
<TouchableOpacity
onPress={() => Linking.openURL("https://petbcc.ufscar.br/ufscar_planner/politica/")}
onPress={() => Linking.openURL("https://github.com/petbccufscar/ufscar-planner/blob/main/PRIVACY.md")}
>
<Text
style={{ ...styles.h3, color: colors.primary }}
Expand Down
15 changes: 7 additions & 8 deletions screens/dashboardScreens/RuSyncScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ import { Buffer } from "buffer";
import { useSelector, useDispatch } from "react-redux";
import { RootState } from "../../redux/reducers";
import { UserState } from "../../redux/types/user";
import { updateUser } from "../../redux/actions/userActions";
import { BalanceErr, tryGetBalance } from "../../helpers/balance";
import {
BalanceErr,
enableBalanceSync,
tryGetBalanceWithToken,
} from "../../helpers/balance";

export default function RUSyncScreen() {
const navigation = useNavigation();
Expand All @@ -25,13 +28,9 @@ export default function RUSyncScreen() {
// setMessageS: (msg: string) => void, // TODO refatorar isso fora.
) {
const encodedAuth = Buffer.from(uname + ":" + password).toString("base64");
const newUser = { ...user, balanceSyncToken: encodedAuth };
const balance = await tryGetBalance(newUser);

// Só queremos saber se o usuário e a senha são válidos.
const balance = await tryGetBalanceWithToken(encodedAuth);
if (typeof balance === "number") {
newUser.money = balance;
dispatch(updateUser(newUser));
enableBalanceSync({ ...user, money: balance }, encodedAuth, dispatch);
Toast.show({ text1: "A sincronização de saldo foi ativada." });
navigation.goBack();
} else if (balance == BalanceErr.AUTH_FAILED) {
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5710,6 +5710,11 @@ expo-notifications@~0.18.1:
fs-extra "^9.1.0"
uuid "^3.4.0"

expo-secure-store@^12.1.1:
version "12.1.1"
resolved "https://registry.yarnpkg.com/expo-secure-store/-/expo-secure-store-12.1.1.tgz#d4992dbb6170882d99d83a440a49864b36904cd1"
integrity sha512-phD8e8mlJWaESUBCpHq0GjS3OiqZ7g+I6SpTGQpt+xSS0pEE1ZUBXnIF+WR2OvoseKiS9ODzDl85CUlut/eNKw==

expo-status-bar@~1.4.4:
version "1.4.4"
resolved "https://registry.yarnpkg.com/expo-status-bar/-/expo-status-bar-1.4.4.tgz#6874ccfda5a270d66f123a9f220735a76692d114"
Expand Down

0 comments on commit acd3d3c

Please sign in to comment.